Wednesday, November 5, 2014

Implement javascript encapsulation with closure

Javascript does not have build-in support for encapsulation, but it can realize the similar function with closure.

First, javascript cannot use scope to hide private method or variable, as local variable and function within a scope are accessible even out of scope, the following code shows this

function test() {
 
   {
  var m = "hello";
  function inner(){
alert("inner");
  }
   }

   alert(m);  //show hello
   inner(); //show inner
}


Second, object scope also does not help for encapsulation, as javascript object initializer cannot have local variables and methods, all properties and methods defined for an object are public, which cannot be used to hide internal implementation.

var Obj = {
      property1 : "my property",
      method1 : function(){
                         alert(this.property1);
                           }
     //cannot define local variable within object scope
}

Obj.method1();


So the only way to support encapsulation for javascript is by using function scope, as a function can define local variable including functions which are only visible inside the function scope. And the function can also return a set of public apis to caller to use. When caller calls the public APIs, the implementation of the Apis as inner function can access all the local variables and functions within the function scope due to the closure. Most javascript framework uses this approach to implement the encapsulation pattern in javascript. The below sample shows the basic idea of this usage.

function MyClass() {

      var privateVar = {
           property1 : "my property",
           method1 : function(){
                         alert(this.property1);
                      }
};

var privateMethod1 = function(v)
  {
  alert(v);
  privateVar.method1();
  };

var publicVariable = {
name: "John",
age: 10
};
var publicMethod = function(){
privateMethod1(privateVar.property1);
} ;
        //expose public method for caller to access
return {
publicFunc: publicMethod,
publicVar : publicVariable
};
}


function test() {
     var obj = MyClass();
     obj.publicFunc(); //call public method to access private info
     alert(obj.publicVar);
     //obj.privateMethod1(); //cannot access private member and throw exception
}

No comments:

Post a Comment