Let's take a look at the purpose of closures. In fact, by using closures, we can do a lot of things. For example, simulate object-oriented code style; express code more elegantly and concisely; and improve code execution efficiency in some aspects.
1 Anonymous self-executing function
We know that if all variables are not added with the var keyword, the default will be added to the properties of the global object. There are many disadvantages to adding such temporary variables to the global object.
For example: other functions may misuse these variables; causing the global object to be too large and affecting the access speed (because the value of the variable needs to be traversed from the prototype chain).
In addition to using the var keyword every time we use the variable, we often encounter a situation in which some functions only need to be executed once and their internal variables do not need to be maintained.
For example, in the initialization of the UI, we can use closures:
The code copy is as follows:
var datamodel = {
table : [],
tree : {}
};
(function(dm){
for(var i = 0; i < dm.table.rows; i++){
var row = dm.table.rows[i];
for(var j = 0; j < row.cells; i++){
drawCell(i, j);
}
}
//build dm.tree
})(datamodel);
We create an anonymous function and execute it immediately, since the external cannot reference variables inside it,
Therefore, it will be released soon after execution. The key is that this mechanism will not pollute the global object.
2 cache
Let’s take another example. Imagine that we have a very time-consuming function object that takes a long time to process each call.
Then we need to store the calculated value. When calling this function, we first look up in the cache. If it cannot be found, we will perform the calculation.
Then update the cache and return the value. If it is found, just return the found value directly. The closure does exactly this, because it does not release external references,
Thus the value inside the function can be preserved.
The code copy is as follows:
var CachedSearchBox = (function(){
var cache = {},
count = [];
return {
attachSearchBox : function(dsid){
if(dsid in cache){//If the result is in cache
return cache[dsid];//Return directly to the object in the cache
}
var fsb = new uikit.webctrl.SearchBox(dsid);//New
cache[dsid] = fsb;//Update cache
if(count.length > 100){//The size of the cache is guaranteed <=100
delete cache[count.shift()];
}
return fsb;
},
clearSearchBox: function(dsid){
if(dsid in cache){
cache[dsid].clearSelection();
}
}
};
})();
CachedSearchBox.attachSearchBox("input1");
In this way, when we call CachedSearchBox.attachSerachBox("input1") the second time,
We can access the object from the cache without creating a new searchbox object.
3 Implement packaging
Let’s first look at an example about encapsulation. The variables inside are not accessible outside the person, but are accessed by providing closures:
The code copy is as follows:
var person = function(){
//The scope of the variable is inside the function and cannot be accessed outside the function
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();
print(person.name);//direct access, the result is undefined
print(person.getName());
person.setName("abruzzi");
print(person.getName());
The results are as follows:
undefined
default
abruzzi
4 Another important purpose of closures is to implement object-oriented objects. Traditional object languages provide class template mechanisms.
In this way, different objects (instances of classes) have independent members and states and do not interfere with each other. Although there is no such mechanism as class in JavaScript, by using closures,
We can simulate such a mechanism. Let’s talk about the above example:
The code copy is as follows:
function Person(){
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
};
var john = Person();
print(john.getName());
john.setName("john");
print(john.getName());
var jack = Person();
print(jack.getName());
jack.setName("jack");
print(jack.getName());
The operation results are as follows:
default
john
default
jack
From this code, we can see that both john and jack can be called instances of the Person class, because the access to the name member is independent and does not affect each other.
The above is the function of js closure, which is very simple and easy to understand. I hope it will be helpful to my friends.