Using Encapsulation With Javascript
Javascript doesn’t natively support encapsulation as OOP languages do. It is however possible to achieve encapsulation with Javascript using a fairly simple workarounds. Encapsulation is done through closures.
Closure
Simple example of a closure is shown below. In Javascript functions have scope so the variable x and function bar are only accessible within the scope of the foo function. They are essentially private and therefore encapsulated to foo.
function foo()
{
var x = 100;
function bar()
{
alert(x);
}
}
Using Closure for Encapsulation
How this helps us, is that private members can be placed in the constructor block using the var and function keyword. Privileged public methods using the this keyword can also be placed in the constructor block. Because these public methods are within the same scope as the private members they have access to them.
var Car = function(make,model)
{
//private properties
var _make, _model;
//private methods
function validate(model)
{
//...
return true;
}
//public privileged methods, have access to private members
this.getModel = function()
{
return _model;
}
this.setModel = function(model)
{
if(validate(model))
_model = model;
else
//...
}
this.getMake = function()
{
return _make;
}
this.setMake = function(make)
{
_make = make;
}
//constructor logic
_make = make;
this.setModel(model);
}
//public non-privileged methods, don’t have access to private members
Car.prototype =
{
display: function()
{
var _return = this.getMake() + " " + this.getModel();
return _return;
}
}
var pinto = new Car("Ford","Pinto");
alert(pinto.display()); //displays "Ford Pinto"
alert(pinto._make); //displays "undefined"
Drawbacks
The drawback to using encapsulation is that so much code is placed in the constructor block. This is bad, because unlike code added to the object’s prototype, a copy of each member in the constructor block is added to memory with the creation of each instance of the Car object. This means only methods which need access to private members should be declared as privileged public methods. This may also mean that if using encapsulation is not need at all, simply adding an underscore to the beginning of member names which are not intended to be part of the exposed API may be enough. Design Patterns.