function A () { var n = 0; This function () { n+ +; Console.log (n); };} var New a (); C.inc (); // Console Output 1c.inc (); // Console Output 2
What is a closure package? This is the closure!! A function that has access to a variable within the scope of another function is a closure. When a function can remember and access the lexical scope in which it is located, a closure is generated, even if the function is executed outside the current lexical scope.
Here the INC function accesses the variable n in constructor A, thus forming a closure.
function A () { var n = 0; function Inc () { n+ +; Console.log (n); } return Inc;} var c = A (); C (); // Console Output 1c (); // Console Output 2
Execution process:
var c=a (); a () here returns the function Inc, which is equivalent to var c = inc;c () equivalent to Inc (); The function name is just an identifier (a pointer to a function), and () is the execution function.
Why do you use closures?
JS Each function is a small black house, it can get outside information, but the outside world can't directly see the content. Put the variable n into the small black room, in addition to the INC function, there is no other way to touch the variable n, and in the function a outside the definition of the same name variable n is not affected, this is called enhanced "encapsulation." And the reason to return function ID Inc with Return is because the INC function cannot be called directly outside of the a function, so return Inc is associated with the outside, and this in the first Code also links Inc to the outside.
Common pitfalls
function Createfunctions () { var result = new Array (); for (var i=0; i <; I++) {Result[i] = function () { return I; }; return result;} var funcs = Createfunctions (); for (var i=0; i < funcs.length; I++
Originally wanted to output 0~9, but the final result is 10 10, why?
The trap here is this: the function band () is the execution function! a simple sentence of var f = function () {alert (' Hi ');}; is not to play the window, followed by a sentence F (); Code inside the function is executed. The above code translates:
varresult =NewArray (), i;result[0] =function(){returnI };//No function is executed, the function is unchanged inside, and I cannot be replaced within the function! RESULT[1] =function(){returnI };//No function is executed, the function is unchanged inside, and I cannot be replaced within the function! . .. result[9] =function(){returnI };//No function is executed, the function is unchanged inside, and I cannot be replaced within the function! i = 10; Funcs=Result;result=NULL; Console.log (i);//Funcs[0] () is the execution of the return I statement, which is the returnConsole.log (i);//Funcs[1] () is the execution of the return I statement, which is the return..... console.log (i);//Funcs[9] () is the execution of the return I statement, which is the return
Why did the garbage collect the result but not the I? Because I am still being referenced by the function. This is the magic of closures, where the internal scope is still present and therefore not recycled. Result still holds a reference to the scope, and this reference is called a closure!
Change method:
functioncreatefunctions () {varresult =NewArray (); for(vari=0; I < 10; i++) {Result[i]=function(x) {return function(){ returnx; }} (i); } returnresult;}varFuncs =createfunctions (); for(vari=0; i < funcs.length; i++) {Console.log (Funcs[i] ());}
Instead of assigning a closure to an array directly, it defines an anonymous function and assigns a value to the array by executing the result of the anonymous function immediately, and takes the parameter I of the For loop in, so that X can find the passed parameter value of 0-10, which explains that the function parameter is passed by value, Therefore, the current value of the variable i is copied to the parameter x. This anonymous function internally creates and returns a closure that accesses X. So since each function in the result array has its own copy of the x variable, it will match our expected output to a different value.
Closure application Scenarios
Two cases of closure application: function as return value, function as parameter pass
1. function as return value
function fn () { var max=10; return function Bar (x) { if (x>max) { console.log (x); } }; } var f1=fn (); F1 (15);
The bar function, as the return value, assigns a value to the F1 variable. When executing F1 (15), the value of the max variable under the FN scope is used.
2. The function is passed as a parameter
var max = ten; var fn=function(x) { if(x>max) { console.log (x); }};( function (f) { var max = +; F ();}) (FN);
The FN function is passed as a parameter into another function, assigned to the F parameter. When you execute F (15), the value of the max variable is 10, not 100, because you are going to create the scope of the function to take the value, not the parent scope.
When a function is called, its execution context is destroyed, and the variables are destroyed at the same time. However, in some cases, after the function call is complete, its execution context is not subsequently destroyed. This is what is needed to understand the core of closures. As follows:
The first step is to generate the global context environment before the code executes and assign values to the variables at execution time. The global context environment is active at this time.
The second step, when executing the 17th line of code, calls FN (), produces the FN () execution context, presses the stack, and sets the active state.
The third step, after executing line 17th, the FN () call is complete. It is supposed to destroy the execution context of FN (), but this cannot be done here. Note that the emphasis is on: Because a function is returned when the FN () is executed. The special thing about functions is that you can create a separate scope. and coincidentally, in the body of the returned function, there is also a free variable Max to refer to in the FN () context under the FN scope. Therefore, this max cannot be destroyed, and Max in the bar function will not be able to find the value after destroying it.
Therefore, the FN () context here cannot be destroyed and still exists in the execution context stack. -that is, when the 18th row is executed, the global context becomes active, but the FN () context is still in the execution context stack. In addition, when you finish line 18th, Max in the global context environment is assigned a value of 100. Such as:
Fourth, executes to line 20th, executes F1 (15), that is, executes bar (15), creates a bar (15) context, and sets it to the active state.
When you execute bar (15), Max is a free variable and needs to be found in the scope where the bar function was created, and the value of Max is 10. This process has been mentioned in the scope chain section.
The point here is that creating the bar function is created when you execute FN (). FN () has long been executed, but the FN () execution context still exists with the stack, so when bar (15), Max can find it. If the FN () context is destroyed, then Max cannot find it.
Obviously, using closures can increase the content overhead!
The fifth step, the execution of 20 lines is the context of the destruction process.
Summarize
A closure is a variable in which a function refers to another function, because the variable is referenced so it is not recycled, so it can be used to encapsulate a private variable. This is the pros and cons, unnecessary closures will only increase memory consumption! also use closures to pay attention to whether the value of the variable matches your requirements, because he is like a static private variable.
JS's closure