Most object oriented programming languages have built-in mechanisms specifically for declaring a member of a class private or public. Javascript doesn’t. Thus, most developers new to Javascript quickly concludes that Javascript do not support private members at all. While it is true that Javascript has no specific mechanism for this, it actually does support private members thanks to the nature of closures.
First, you must understand two things. The first is how closures basically work:
function closure1() {
// all new variables declared in here is not
// visible outside the scope of closure1
var a = 'test';
}
a // gives "a is not defined"
In Javascript, all new variables defined inside the scope of a function, is not visible/accessible to the code surrounding the function.
The second thing you must understand is this way of declaring a class:
function Dog() {
this.bark = function() {
alert('VROOOF!');
};
}
var fido = new Dog();
fido.bark(); // gives an alert box saying "VROOOF!"
The reason this works is that this inside the Dog function (which acts as the constructor) actually equals fido – it IS the instantiated object. By defining methods on this you are essentially defining singleton methods (at least that is what rubyists call it) for the instantiated object.
With these two things in mind, consider this:
function Dog() {
var sleeping = false; // this is a private variable!
function sound() { // and a private method!
return sleeping ? 'ZzZzzz' : 'VROOOF!';
}
this.bark = function() {
alert(sound()); // this public method has access to the private method
};
this.sleep = function() {
sleeping = true;
};
}
var fido = new Dog();
fido.bark(); // VROOOF!
fido.sleep();
fido.bark(); // ZzZzzz
As you can see the public methods (bark and sleep) have access to the private members (sleeping and sound). Outside Dog sleeping and sound is not visible and thus hidden from the rest of the program. Hurray!
There is one important caveat to this construct though. It takes up more memory than the traditional Dog.prototype = {} way (with which you cannot use private members). Usually though, this extra memory consumption is too little to notice.
Have fun writing beautiful object oriented javascript! :-)