1, first we need to know the variable scope chain
The scope of a variable is divided into two types: global variables and local variables. A variable defined in any function is a global variable, and a variable defined in a function is a local variable, so be sure to use the var keyword when defining a variable inside a function, and a variable with the VAR keyword as a global variable.
Each piece of code in JavaScript has a chain of scopes associated with it, which is a list of objects or lists that define the variables in the scope of the code. The scope of the top-level code is made up of global variables; there are two objects in the scope chain of a function that does not contain nested functions: One is the object of a defined function parameter and a local variable, one is a global variable object, and the scope chain of a nested function has three objects: function parameters and local variables--parameters of external functions and local variables--global variables. Functions can access objects on the scope chain, so a function can access global variables, and vice versa, that is, you cannot access local variables within a function outside of a function.
1 2 3 4 5 6 7 8 9 10 |
var a=1; Function Wai () {alert (a); var m=10; n=20;} Wai (); => 1; The global variable alert (m) can be accessed within the function. => error; External Access function local variable error alert (n); => 20; Variables defined within the function are not using the var keyword, so are global variables that can be accessed externally |
2. How to read local variables externally
Sometimes we need to access local variables on the inner plate of the function externally, and this time we need to use workarounds to implement them. We use JavaScript variable scope characteristics, in the function of the definition of the child function, the child function 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; The Nei () function is a local variable and cannot be accessed externally by f (); => 10; |
3. Closure Package
The Nei () function of the previous code is a closure, from which it is known that a closure is a function that can read a local variable within a function, a function that is defined inside a function, and is essentially considered a bridge within and outside the function.
The closure has two functions:
One is the previous reference to the variables that can be read inside the function
Second, these local variables can be stored in memory, the implementation of 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; |
Above example when the Wai () function runs, the variable m is saved in memory, and the F () can read the value of M, but 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 incoming parameter to the local variable i in the anonymous function and increases the I self;
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 get a deeper understanding of closures, let's look at one of the following examples:
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 have written that.
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); => contains an array of five function bodies alert (a[0] ()); => 5; Alert (A[1] ()); => 5; |
The code above finds that the pop-up is 5, rather than the 0,1,2,3,4 we envision, this is 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 the value of the entire box () function is constantly growing.
Solution: Closure of the implementation of
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, the use of closure considerations
1 because the closure will make the function of the variables are stored in memory, memory consumption is very large, so can not abuse the closure, otherwise it will cause Web page performance problems, in IE may lead to memory leaks. The workaround is to remove all unused local variables before exiting the function.
2 The closure will change the value of the inner variable of the parent function outside the parent function. So, if you use the parent function as an object, using the closure as its common method, and the internal variable as its private property (private value), be careful not to arbitrarily change the value of the parent function.
5, the following is from a few on the closure of the study questions
If you can understand the operating results of the following code, you should understand the closure mechanism.
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;//=> nested function's This is a global variable or UN Defined, this} of the parent function is not inherited; } }; Alert (Object.getnamefunc () ()); The Window |
The above output is "the window" because this does not inherit the parent function this, its value is global or undefined (ECMASCRIPT5), and therefore returns the name variable for the global object. To return the Name property of object, 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 to the CUR variable, and its nested function can access its properties through the cur variable.
------------------------------------------------------------------------------------------------------
JavaScript Closures Example
1 2 3 4 5 6 7 8 9 10 |
function Outerfun () {var a=0; function Innerfun () {a++; alert (a);}} innerfun (); =>error |
The code above is wrong. The scope of the Innerfun () is called Inside the Outerfun () and it is wrong to invoke it outside the Outerfun ().
Change to the following, which 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 (a);} return innerfun;//Note here} var obj=outerfun (); obj (); The result is 1 obj (); The result was 2 var obj2=outerfun (); Obj2 (); The result was 1 obj2 (); Result is 2 |
What is closure:
When an intrinsic function is referenced outside the scope that defines it, the closure of the internal function is created, and if the intrinsic function references a variable that is located in an external function, the variables are not freed in memory when the external function is called, because the closures require them.
--------------------------------------------------------------------------------------------------------
Let's look at an example.
JS Code
1 2 3 4 5 6 7 8 |
function Outerfun () {var a =0; alert (a);} var a=4; Outerfun (); => 0 alert (a); => 4 |
The result is 0,4. Because the VAR keyword is used inside the function to maintain a scope within outfun ().
Then look at the following code:
JS Code
1 2 3 4 5 6 7 8 9 |
function Outerfun () {//no var a =0; alert (a);} var a=4; Outerfun (); => 0 alert (a); => 0 |
The result is 0, 0 is really strange, why?
A
Scope chain is a term that describes a path along which you can determine the value of a variable. When a=0 is executed, because the VAR keyword is not used, the assignment operation is linked to the Var a=4 along the scope and changes its value.