Javascript function closures and design of encapsulated javascript object and class
In the previous article "Add property to Javascript Object in "jQuery" style and "One line properties setter and getter for Javascript class", we use the technique of function closures to create private variables for an object as well as private varibles for a javascript class. Let's examine the concept behind: function closures:
Variables declared inside a function using reserved word "var" are local to the function, i.e., the variables are independent to variables outside the function. Let's see the following code:
var a="15";
function inner(){
var a="16";
}
inner();
document.write(a);

view the online example
We've set the variable "a" to "16" inside a function inner(). Since variable "a" inside function inner() is independent to the variable "a" outside the function, the output is remain unchanged as "15" instead of "16". This is called "function closure".
How we can make use of function closure to mimic a private varibles to an object? Firstly, let's study the following code:
function closures(obj){
var data;
obj.getData=function(){return data}
obj.setData=function(e){data=e}
}
a={};
b={};
closures(a);
closures(b);
a.setData(234);
document.write("a="+a.getData()+"<"+"br/>");
b.setData("abc");
document.write("b="+b.getData()+"<"+"br/>");
view the online example
There will be a separated variable "data" each time the function closeures() is called. In the above example, function closures() have been called twice, thus there will be two different variable "data", one for the object "a" and the other for the object "b".
In order to illustrate this, I am going to use the function closures() twice for one object only. If we set the data after the first closure() is called. After setting the data as "abc", we call the closure() again, the old data will be "overrided" by the new instance. Thus, the value of "data" will be displayed as "undefined". You can verify this using the following code:
function closures(obj){
var data;
obj.getData=function(){return data}
obj.setData=function(e){data=e}
}
a={};
closures(a);
a.setData("abc");
closures(a);
document.write("a="+a.getData()+"<"+"br/>");
view the online example
If we modify the function closure to allowing adding the name of the variable, we can create any private property anytime we'd like to. The code will be:
function closures(obj, name){
var data;
obj["get"+name]=function(){return data}
obj["set"+name]=function(e){data=e}
}
a={};
closures(a,"Data");
a.setData("abc");
document.write("a="+a.getData()+"<"+"br/>");
view the online example
However, the function is useless if we cannot limit the variable to certain value. This can be done by refining the setter function. For example, we create a Javascript Object "person" with adding an "age" property to it. In order to limit the age to number, the code can be written as:
function closures(obj, name){
var data;
obj["get"+name]=function(){return data}
obj["set"+name]=function(e){if (typeof e=="number") data=e}
}
person={};
closures(person,"Age");
person.setAge(19);
document.write("My age is "+person.getAge()+"<"+"br/>");
view the online example
We can extend or generalize our closure() function to any rules by adding the checking rule each time the closure() is called:
function closures(obj, name, rule){
var data;
obj["get"+name]=function(){return data}
obj["set"+name]=function(e){if (rule && rule(e)) data=e}
}
person={};
closures(person,"Age",function(x){return typeof x=="number"});
person.setAge(19);
document.write("My age is "+person.getAge()+"<"+"br/>");
view the online example
Not bad, isn't it? That the basis for an "Encapsulated Javascript Object" and "Encapsulated Javascript Class"
Previous in This Category: One line properties setter and getter for Javascript class Next in This Category: jscript Utility for VBScript, ties two extreme and leads to an even better web development la
