Understanding of javascript closures
1. First, we need to know the variable scope chain.
There are two scopes of variables: global variables and local variables. The variables in no function are defined as global variables and the variables defined in the function are local variables. Note that the var keyword must be used when defining variables in the function, variables without the var keyword are global variables.
Every piece of code in javascript has an associated scope chain. This scope chain is an object list or linked list that defines the variables in the code "Scope. The scope of top-level code consists of global variables. The scope chain of a function that does not contain nesting has two objects: one is the defined function parameter and the other is the global variable object; the scope chain of nested functions has three objects: function parameters and local variables-external function parameters and local variables-global variables. A function can access objects in the scope chain. Therefore, a function can access global variables, but in turn cannot access local variables in a function outside the function.
| 1 2 3 4 5 6 7 8 9 10 |
Var a = 1; Function wai (){ Alert (); Var m = 10; N = 20; } Wai (); // => 1; global variables can be accessed inside the Function Alert (m); // => error; an error is returned for the local variable of the external access function. Alert (n); // => 20; variables defined in the function do not use the var keyword. Therefore, they are global variables and can be accessed externally. |
2. How to read local variables externally
Sometimes, we need to access the local variables in the function board from the outside, so we need to use a work und to implement this. Using the features of the javascript variable scope, we define sub-functions in the function so that sub-functions can access the variables in the parent function.
| 1 2 3 4 5 6 7 8 9 10 11 |
Function wai (){ Var m = 10; Function nei (){ Alert (m ); } Return nei; } Var f = wai (); Nei (); // => error; nei () function is a local variable and cannot be accessed externally. F (); // => 10; |
3. Closure
The nei () function of the previous code is a closure. It can be seen from the above that the closure is a function that can read local variables within the function and is a function defined inside the function, essentially, it can be considered as a bridge between the function and the function.
The closure has two functions:
First, the variables mentioned above can be read inside the function.
Second, you can store these local variables in the memory for variable data sharing.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 |
Function wai (){ Var m = 99; Function nei (){ Alert (m ); M ++; } Return nei; } Var f = wai (); F (); // => 99; F (); // => 100; F (); // => 101; |
In the preceding example, when the wai () function is run, the variable m is saved to the memory, and the m value can be read by executing f (), but the direct alert (m) is not allowed!
We can also pass parameters to the closure function, as shown in the following example, to define an anonymous function and return a closure function, which adds the input parameters to the local variable I in the anonymous function, and enable I auto-increment;
| 1 2 3 4 5 6 7 8 9 10 11 |
Var wai = (function (){ Var I = 0; Return function (num ){ Num + = I; Alert (num ); I ++; } })(); Wai (1); // 1 Wai (2); // 3 Wai (3); // 5 |
To better understand the closure, let's look at the following example:
Now I want to define a function. This function returns an array, and each element of the array is a function. The corresponding index value is displayed for each function.
We may write it like this.
| 1 2 3 4 5 6 7 8 9 10 11 |
Function box (){ Var arr = []; For (I = 0; I <5; I ++ ){ Arr [I] = 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 code above found that the pop-up is 5, instead of the expected, 4, because I is also a local variable in the memory, when we run a [0] () the value of I is 5, and the value of I is constantly increasing throughout the running process of the box () function.
Solution: Implementation of closures
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Function box (){ Var arr = []; For (var I = 0; I <5; I ++ ){ Arr [I] = (function (num ){ Return function () {return num ;} }) (I ); } Return arr; } Var arr = box (); For (var I = 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 be stored in the memory, the memory consumption is very large, so the closure cannot be abused, otherwise it will cause the performance of the web page, memory leakage may occur in IE. The solution is to delete all unused local variables before exiting the function.
2) The closure changes the value of the internal variable of the parent function outside the parent function. Therefore, if you use the parent function as an object, use the closure as its Public Method, and use internal variables as its private value ), be sure not to change the variable value of the parent function.
5. The following are some questions about closures:
If you can understand the running results of the following code, you should understand the operating mechanism of the closure.
Js Code
| 1 2 3 4 5 6 7 8 9 10 |
Var name = "The Window "; Var object = { Name: "My Object ", GetNameFunc: function (){ Return function (){ Return this. name; // => this of the nested function is a global variable or undefined and does not inherit this of the parent function. }; } }; Alert (object. getNameFunc (); // The Window |
The preceding output is "The window" because in nested functions, this does not inherit The parent function this, and its value is a global variable or undefined (under ECMAScript5 ), therefore, the name variable of the global object is returned. The Code is as follows:
| 1 2 3 4 5 6 7 8 9 10 11 |
Var name = "The Window "; Var object = { Name: "My Object ", GetNameFunc: function (){ Var cur = this; Return function (){ Return cur. name; }; } }; Alert (object. getNameFunc (); // = "My Object |
The code above assigns this of the parent function object to the cur variable, and its nested function can access its attributes through the cur variable.
Bytes ------------------------------------------------------------------------------------------------------
JavaScript closure example
| 1 2 3 4 5 6 7 8 9 10 |
Function outerFun () { Var a = 0; Function innerFun () { A ++; Alert (); } } InnerFun (); // => error |
The above code is wrong. innerFun () is in the scope of outerFun (), and it is wrong to call it outside outerFun.
Change it to the following, that is, the closure:
Js Code
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Function outerFun () { Var a = 0; Function innerFun () { A ++; Alert (); } Return innerFun; // note the following: } Var obj = outerFun (); Obj (); // The result is 1. Obj (); // The result is 2. Var obj2 = outerFun (); Obj2 (); // The result is 1. Obj2 (); // The result is 2. |
What is a closure:
When an internal function defines its external scope as being referenced, it creates a closure for the internal function. If the internal function references a variable in the external function, after an external function is called, these variables will not be released in the memory because the closure needs them.
Bytes --------------------------------------------------------------------------------------------------------
Let's look at an example.
Js Code
| 1 2 3 4 5 6 7 8 |
Function outerFun () { Var a = 0; Alert (); } Var a = 4; OuterFun (); // => 0 Alert (a); // => 4 |
The result is. Because the var keyword is used inside the function to maintain the scope of a within outFun.
Let's look at the following code:
Js Code
| 1 2 3 4 5 6 7 8 9 |
Function outerFun () { // No var A = 0; Alert (); } Var a = 4; OuterFun (); // => 0 Alert (a); // => 0 |
The result is 0, 0. Why?
The scope chain is the term used to describe a path. The variable value can be determined along this path. when a = 0 is executed, because the var keyword is not used, the value assignment operation will link to var a = 4 along the scope and change its value.