Details on the purpose of the js closure
- 2020-03-30 04:16:54
- OfStack
Let's look at what closures are for. In fact, we can do a lot of things by using closures. For example, simulate the object-oriented code style; More elegant, more concise expression of the code; Improve code execution in some way.
Anonymous self-executing function
We know that all variables, if we don't add the var keyword, will be added to the properties of the global object by default. There are many disadvantages to adding temporary variables to the global object.
For example, other functions may misuse these variables; Global objects are too large, affecting the speed of access (because the values of variables need to be traversed from the prototype chain).
In addition to using the var keyword every time a variable is used, we often encounter situations in which a function only needs to be executed once and its internal variables are not maintained.
For example, if the UI is initialized, we can use closures:
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, because the outside can't reference its internal variables,
Therefore, it will be released soon after execution. The key is that this mechanism does not pollute the global object.
2 the cache
So let's take another example, and let's say we have a function object that takes a long time to process, that takes a long time to call,
So we need to store the calculated value, and when we call this function, we first look it up in the cache, and if we can't find it, we calculate,
Then update the cache and return the value, if found, simply return the value found. Closures do exactly that, because they don't release external references,
So that the values inside the function can be preserved.
var CachedSearchBox = (function(){
var cache = {},
count = [];
return {
attachSearchBox : function(dsid){
if(dsid in cache){//If the result is in the cache & PI; < br / >
return cache[dsid];//Directly returns the object in the cache & NBSP; < br / >
}
var fsb = new uikit.webctrl.SearchBox(dsid);//New < br / >
cache[dsid] = fsb;//Update cache & NBSP; < br / >
if(count.length > 100){//Size of positive cache <= 100 < br / >
delete cache[count.shift()];
}
return fsb;
},
clearSearchBox : function(dsid){
if(dsid in cache){
cache[dsid].clearSelection();
}
}
};
})();
CachedSearchBox.attachSearchBox("input1");
That way, when our second call CachedSearchBox. AttachSerachBox (" input1 "),
Instead of creating a new searchbox object, we can retrieve the object from the cache.
3 implementation encapsulation
You can start with an example of encapsulation, where there is no access to its internal variables outside of person, but by providing a closure:
var person = function(){
//The variable scope is inside the function and cannot be accessed from the outside. < br / >
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();
print(person.name);//Direct access, result undefined&awards; < br / >
print(person.getName());
person.setName("abruzzi");
print(person.getName());
The result is:
Undefined
Default
Abruzzi
Another important use of closures is to implement objects in object orientation. Traditional object languages provide a templating mechanism for classes.
Such different objects (instances of classes) have separate members and states that do not interfere with each other. Although there is no mechanism for classes in JavaScript, by using closures,
We can simulate this mechanism. Let's do the same thing with the above example:
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 result is as follows:
Default
John
Default
Jack
From this code, we know that both John and jack can be called instances of the class Person, because the two instances have independent access to the member name.