Closures are a difficult part of JavaScript, but they are also a very important point of knowledge.
1, first we must know the variable scope chain
The scope of a variable is divided into two types: global variables and local variables. Variables that are not defined in any function are global variables, variables defined in the function are local variables, note that the VAR keyword must be used when defining variables inside a function, and variables without the VAR keyword are global variables.
Each piece of code in JavaScript has a scope chain associated with it, which is a list of objects or lists that define the variables in the scope of this code. The scope of the top-level code is made up of global variables; a scope chain that does not contain nested functions has two objects: one is a defined function parameter and a local variable object, one is a global variable object, and the scope of a nested function has three objects: function parameters and local variables--parameters and local variables of external functions--global variables. A function can access an object on a scope chain, so a function can access a global variable, which in turn cannot, that is, a local variable inside a function that cannot be accessed outside of the function.
var a=1; function Wai () { alert (a); var m=10; n=20;} Wai (); // = 1; The global variable alert (m) can be accessed inside the function ; // = = error; external access function local variable error alert (n); // = + ; Variables defined inside the function do not use the var keyword, so it is a global variable that can be accessed externally
2. How to read the local variables externally
Sometimes we need to access the local variables of the function's inner panel externally, and we need to use a workaround to do so. We use JavaScript variable scope to define sub-functions within the function, and the child functions can access the variables in the parent function.
function Wai () { var m=10; function nei () { alert (m); } return nei;} var f = wai ();
Nei (); = error; The Nei () function is a local variable that cannot be accessed outside F () ; // = Ten;
3. Closed Package
The Nei () function of the previous piece of code is a closure, from which the closure is a function that can read local variables inside a function, a function that is defined inside a function, which can essentially be thought of as a bridge between the inside of the function and the outside of the function.
There are two effects of closures:
One is that the variables inside the function can be read as mentioned earlier
The second is to allow these local variables to be stored in memory, to implement variable data sharing
function Wai () { var m=99; function nei () { alert (m); M++ ; } return nei;} var f= Wai (); F (); // * = ; f (); // = +; f (); // = 101;
When the Wai () function runs, the variable m is saved in memory, and the F () can read the M value, but the direct alert (m) is not possible!
We can also pass parameters to the closure function, as shown in the following example, define an anonymous function and return a closure function that adds the passed in parameter to the local variable i in the anonymous function and makes I self-increment;
var wai= (function() { var i=0; return function (num) { num+ =i; alert (num); I+ +; }}) (); Wai (1); // 1Wai (2); // 3Wai (3); // 5
To get a deeper understanding of closures, let's look at the following example:
Now I want to define a function that returns an array, and each element of the array is a function, and each function pops up the corresponding index value
We might be writing this.
function box () { var arr=[]; for (I=0;i<5;i++ =< Span style= "color: #0000ff;" >function () {return I;} return arr; var a=box (); alert (a); // => an array containing five function bodies alert (a[0] () ); // => 5; Alert (A[1] ()); // => 5;
The above code finds that the pop-up is 5, not the 0,1,2,3,4 we expected, because I is also a local variable that exists in memory, and when we run A[0] (), the value of I is already 5,i value is constantly increasing during the entire box () function.
Workaround: Closure Implementation
functionbox () {varArr=[]; for(vari=0;i<5;i++) {Arr[i]=(function(num) {return function(){returnnum;} }) (i); }returnarr; }varArr=box (); for(vari=0;i<5;i++) {alert (Arr[i] ());//0,1,2,3,4}
4. Precautions for using closures
1) Because the closure will make the variables in the function are stored in memory, memory consumption is very large, so can not abuse closures, otherwise it will cause the performance of the Web page, in IE may cause memory leaks. The workaround is to remove all unused local variables before exiting the function.
2) The closure changes the value of the inner variable of the parent function outside the parent function. So, if you use the parent function as an object, and the closure as its public method, and the internal variable as its private property (private value), be careful not to arbitrarily change the value of the parent function's variable.
5, the following is from a few about the closure of the study questions
If you can understand the results of the following code, you should understand the closure of the operation mechanism.
JS code
var name = "The window" ; var object = {name: " My object ", Getnamefunc: function () { Span style= "color: #0000ff;" >return function () { return this . Name; // => nested function is a global variable or undefined and does not inherit this of the parent function. }; } }; Alert (Object.getnamefunc () ()); // the window
The
above is output as "the window" because in the nested function this does not inherit the parent function this, whose value is a global variable or undefined (ECMAScript5), so the name variable returned as the global object. To return the Name property of object, the code is as follows:
var name = "the window"; var object = { "My object", function() { var cur=this; return function () { return cur.name;};} ; // = "My Object"
The code above assigns the this of the parent function object to the CUR variable, and its nested function can access its properties through the cur variable.
--------------------------------------------------------------------------------------------------------
JavaScript Closures Example
function Outerfun () {var a=0; function Innerfun () {a+ +; alert (a);}} Innerfun (); // =>error
The above code is wrong. The scope of Innerfun () is inside Outerfun () and it is wrong to call it outside the Outerfun ().
Change to the following, i.e. closures:
JS Code
functionOuterfun () {varA=0; functionInnerfun () {a++; alert (a); } returnInnerfun;//Watch this .}varobj=outerfun (); obj ();//result is 1obj ();//result is 2varObj2=Outerfun (); Obj2 ();//result is 1Obj2 ();//result is 2
What is a closure package:
When an intrinsic function is referenced outside the scope that defines it, the inner function's closure is created, and if the intrinsic function references a variable that is located outside the function, when the external function is called, the variables are not freed in memory because the closures require them.
--------------------------------------------------------------------------------------------------------
Let's look at one more example
JS Code
function Outerfun () { var a =0; alert (a); }var a=4; Outerfun (); // = 0alert (a); // = 4
The result is 0,4. Because the VAR keyword is used inside a function to maintain the scope of a within outfun ().
Then look at the following code:
JS Code
function Outerfun () {//a =0; alert (a);} var a=4; Outerfun (); // = 0alert (a); // = 0
The result is 0, 0 is really strange, why?
A scope chain is a term that describes a path that can be used to determine the value of a variable. When a=0 is executed, the assignment is linked to Var a=4 along the scope, because the VAR keyword is not employed; and change its value.
Understanding of JavaScript closures