This series has not been updated for a long time. I will take it again today and continue with the previous unfinished items. In this article, we will talk about the reference of closure, one of the most important features in Javascript. One of the most important features of Javascript is the use of closures. Because of the use of closures, the current scope can always access external scopes. Because Javascript has no block-level scope and only function scope, the use of closures is closely related to functions.
Simulate private variables
The Code is as follows:
Function Counter (start ){
Var count = start;
Return {
Increment: function (){
Count ++;
},
Get: function (){
Return count;
}
}
}
Var foo = Counter (4 );
Foo. increment ();
Foo. get (); // 5
Counter returns two closures: increment and get. These two functions maintain access to the Counter scope, so they can access the variable count defined in the Counter scope.
Working Mechanism of private variables
Because Javascript cannot assign values or reference scopes, In the above example, there is no way to directly access the internal private variable count from outside. The only way is to access the service by defining the closure.
The Code is as follows:
Var foo = new Counter (4 );
Foo. hack = function (){
Count = 1337;
};
The above Code does not change the count variable value in the Counter scope, because hack is not defined in Counter. The above Code only creates or overwrites the global variable count.
Closure in a loop
The most common mistake is to use a closure in a loop.
The Code is as follows:
For (var I = 0; I <10; I ++ ){
SetTimeout (function (){
Console. log (I );
},1000 );
}
The above Code does not output 0 to 9, but outputs 10 consecutive times.
The above anonymity keeps a reference to variable I. When the console. log function is called to start output, the loop has ended, and the variable I is 10.
To avoid the above errors, we need to create a copy of the variable I value in each loop.
Avoid reference errors
To copy the value of a variable in a loop, the best way is to add an anonymous immediate execution function to the outer layer.
The Code is as follows:
For (var I = 0; I <10; I ++ ){
(Function (e ){
SetTimeout (function (){
Console. log (e );
},1000 );
}) (I );
}
This external anonymous function receives the cyclic variable I as the first parameter and copies its value to its own parameter e.
The external anonymous function passes parameter e to setTimeout, so setTimeout has a reference pointing to parameter e. In addition, the value of e will not change because of the External Loop.
Another way to achieve the same effect is to return an anonymous function in the anonymous function in setTimeout:
The Code is as follows:
For (var I = 0; I <10; I ++ ){
SetTimeout (function (e ){
Return function (){
Console. log (e );
}
}) (I), 1000)
}
In addition, the bind method can also be used.
The Code is as follows:
For (var I = 0; I <10; I ++ ){
SetTimeout (console. log. bind (console, I), 1000 );
}
At the end of this article, we will summarize the following:
(1) closure is a design principle. It analyzes the context to simplify user calls, so that users can achieve their purpose without knowing it;
(2) the mainstream articles on closure analysis on the Internet are actually opposite to the closure principle. If you need to know the closure details, this closure fails to be designed;
(3) Try to learn as little as possible.