How to create an object with private variables and methods
In short, you can use private variables when you return another scope when declaring a class.
-
function Cats() {
-
var nameList = []; // private var
-
-
// This is where you define another scope!
-
return {
-
add:function(name) {
-
nameList.push(name);
-
}
-
}
-
}
How does it work?
The magic lies in creating a different scope at the end of the class definition that does not include private variables. Then, private members are available in this scope and not outside of it, thanks to the power of closures.
Differences between private and public
These two classes definition shows the difference between the a class where all members are public versus a class where some members are private.
This is a class where all members are public.
-
function PublicCats() {
-
// This is the list of cat names
-
this.nameList = [];
-
-
// This is a method that I would like to be private but can’t
-
// It returns the last cat of the list
-
this.lastCat = function() {
-
return this.nameList[this.nameList.length-1];
-
}
-
-
// Return the list of names
-
this.names = function() {
-
return this.nameList;
-
}
-
-
// Add a name to the list
-
this.add = function(name) {
-
this.nameList.push(name);
-
-
// Return the last cat just added
-
return this.lastCat();
-
}
-
}
This is the corresponding class where some members are private.
-
function PrivateCats() {
-
// This is the list of cat names
-
var nameList = [];
-
-
// This is a private method
-
var lastCat = function() {
-
// Note : I don’t use "this" to access private variables
-
// thanks to the power of closures!
-
return nameList[nameList.length-1];
-
}
-
-
// These are our public methods!
-
// This is where we create another scope to
-
// avoid external objects to use the private variables.
-
return {
-
add:function(name) {
-
// Note : once again, I don’t use "this"
-
// to access the private variables and methods
-
nameList.push(name);
-
return lastCat();
-
},
-
names:function() {
-
return nameList;
-
}
-
}
-
}
In the above code, line 15 makes all the difference between the two classes.
On GitHub
Get all the code on GitHub and see it live in action on my GitHub page.


[...] [UPDATE : This post is outdated. Check out the new post on how to create objects.] [...]
The only thing about specifying your scope in the return object, is that it can be confusing to read (or see where public vs private stops… this is totally just a semantic quibble but:
function PrivateCats() {
var klass = {};
var privateFunction = function () {};
klass.publicFunction = function () {};
return klass;
}
Seems to be a little easier to read.
@Topper There’s a hundred ways of assigning functions and I picked the easiest one to understand but it may be hard to read when the class grows. Sometimes, I use _privateMethod() to distinguish them easily from public methods but I’m not decided if I should really use this notation.
Anyways, thanks for your thoughts! Someone that would read the comments would see other ways to do it.
I don’t see the advantage to using private variables as opposed to namespacing. Sure it may be accessible outside of the function, but the fact that it’s namespaced means there wont be any problems with variable name collisions right?
e.g.
function foo(){
foo.bar={};
}
var bar={}; //no collision
@Yansky It’s less about collisions and more about cleaner code. If all the methods of an object are public, it could be a harder for other programmer to use your code.
Scoping variables is one of the base OO principle: encapsulation. This is the main reason I think to do it.
Also, why not simply do
function PrivateCats() {
// This is the list of cat names
var nameList = [];
// This is a private method
var lastCat = function() {
// Note : I don’t use “this” to access private variables
// thanks to the power of closures!
return nameList[nameList.length-1];
}
// These are our public methods!
// This is where we create another scope to
// avoid external objects to use the private variables.
this.add = function(name) {
// Note : once again, I don’t use “this”
// to access the private variables and methods
nameList.push(name);
return lastCat();
},
this.names = function() {
return nameList;
}
}
Seems even more simple I think… And works the same since this isn’t in the same scope as the var declarations. Maybe I missed something… I’m starting to become rusted in JS
Oups… Forgot to remove the return line
Simpler sample:
function test(){
var rot=”a”;
this.rotted=function(){return rot};
}
var test2 = new test()
alert(test2.rot); //returns undefined
alert(test2.rotted()); //returns a
Forgot to remove the “return” line.
Here is a simpler example:
function test(){
var rot=”a”;
this.rotted=function(){return rot};
}
var test2 = new test()
alert(test2.rot); //Returns undefined
alert(test2.rotted()); //Returns a
@BK You could do it that way to. I just prefer the other notation… thanks for commenting about this way of doing things.
Keep them coming, I’ll probably write a post about how many different ways of using private variables in an object
[...] the new solution using a private variable for the [...]
yes,the essential is closure!