This article does not talk about the concept of closures, because the concept of easy to confuse people, this article hope that through a few vivid examples to explore the nature of closures, I believe that the understanding of closures will help.
Procedure 1
var f = (function() { var n = ten; return function () { + +N; Console.log (n); }}) (); F ();
Output:
11
Conclusion:
The closure function can access variables in the outer function.
Procedure 2
var arr = [];(function() { var n = 0; for (var i=0; i<3; + +i) {function() {+ +N; Console.log (n);}} ) (); for (var i=0; i<3; + +i) {var f = arr[i]; f ();}
Output:
123
Conclusion:
In a function with multiple closure functions, these closure functions share variables in the outer function. As you can see, n in the 3 closure functions in the example is the same variable, not 3 copies of the variable.
Procedure 3
var function () { + +N; Console.log (n);} var f = (function() { var n = ten; return F0;}) (); F ();
Output:
The error points to the line "++n".
Conclusion:
The scope of a closure function is not determined at the time it is referenced or run, it seems to be determined when it is defined.
Description
Although the program looks the same as "program 1", because the function f0 an internal definition of an externally defined, although they are all returned from within the function, in this case F0 cannot access the variable N.
Procedure 4
var f = (function() { var n = ten; return New Function (' ++n;console.log (n); ' );}) (); F ();
Output with "Program 3":
Conclusion:
This procedure is further confirmed and supplemented by the procedure 3. The conclusion that can be drawn from the program is that the scope of the closure function is determined when it is compiled.
Description
You can use the function constructor to create a function object, which is specified using a string that can be executed like a normal function and compiled on first execution. Therefore, although this function object is defined inside the anonymous functions, it is not compiled until it is called, that is, when it is executed to "F ()", and the scope of the original function does not exist at this time.
Let's look at an example:
Procedure 5
var f = (function() { var n = ten; return eval (' (function () {++n;console.log (n);}) ' );}) (); F ();
Output:
11
Conclusion: No
Description
This example is a supplement to the above two programs. This example can print 11 as "Program 1" because the eval () function immediately parses (compiles and executes) the string passed to it, so the function defined with eval is equivalent to the directly defined effect.
(Note: "function () {...}" in Eval () Must be expanded with parentheses, or it will be an error.)
Procedure 6
var f = (function() { var n = ten; var s = ' Hello '; return function () { + +N; Console.log (n); }}) (); F ();
Run-time in "Console.log (n);" This line adds a breakpoint to view the values in the scope, where only n does not have s:
Conclusion:
Variables that are not used in the enclosing function in the outer function are not visible to the closure function. In this example, the closure function does not reference the variable s, so there is only n in its scope. That is, for a closure function, the variable of the outer function that it can access is actually a subset of the actual outer function variable.
Procedure 7
This program is used to prove the conclusion of "program 6" through data. The program is a little bit more complicated and will be explained briefly later.
varFunarr = [];varLENGTH = 500;varALPHABET = ' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ';functionGetstr () {vars = '; for(vari=0; i<length; ++i) {s+ = Alphabet[math.floor (Math.random () * 62)]; } returns;}functionGetarr () {varA =NewArray (LENGTH); for(vari=0; i<length; ++i) {A[i]=Math.random (); }}varf =function( ) { varn = 10; vars =Getstr (); varA =Getarr (); Funarr.push (function() {Console.log (n, S, a); //---1Console.log (n);//---2 })} for(vari=0; i<2000; ++i) {f ();}
Program Analysis:
The focus of this program is for loop and function f. The function F 2000 times is called in the For loop, and each call creates a number and two string and array of length 500, so the size of the local variable created by the 2000-time function call is quite considerable, and the program uses this method to compare the results when the analysis is done later.
The local variables in F are referenced by a closure function to see if the unreferenced local variables are recycled.
Run the program two times, using statement 1 (which references all local variables in F) for the first time, and the second using statement 2 (only reference the number variable N). The results obtained from the run 1 and the result 2 are collected heap snapshots (heap Snapshot):
You can see that the amount of memory varies enormously, and from here you can get a preliminary conclusion that "local variables that are not referenced by the closure function will be recycled."
But in order to be rigorous, we need to do a more detailed analysis. The first is the chart of results 1 and result 2:
As you can see, the number of objects in memory after the second run is significantly less than the first (the number of intermediate objects produced is the same), which further illustrates that most of the objects are recycled after the second run.
Finally, we compare the result 2 with the result 1, and the result is as follows:
Conclusion:
A local variable in a function that is not referenced by any closure function (which is not considered by a global variable) can be reclaimed after the function has finished running, otherwise these variables will be retained as part of the scope of their closure function until all the closure functions have been executed.
This conclusion also confirms the conclusion of "program 6": The reference to the outer-layer function scope of the closure function is a subset of the real scope of the external function.
In addition, it can be inferred from this experiment that the outer function will be recycled after the execution is finished. Since the function's internal variables have been recycled, the function itself does not have any meaning.
Some studies of JavaScript closures