Closures are functions that have access to variables in another function scope. A common way to create closures is to create another function inside one function. Essentially, a closure is a bridge that connects the inside of the function with the outside of the function.
function A () { var i = 0; function B () { alert (+ +i) ; } return b;} var c =//1
Function b is nested in function A, and function B is returned.
After executing var c = A (), the variable C actually points to function B, and then C () pops up a window showing the value of I.
When function A's intrinsic function B is referenced by a variable outside function A, a closure is created.
Closures mainly involve several other features of JS: Scope chain, garbage (memory) recovery mechanism, function nesting
function Compare (value1, value2) { if(value1 > value2) { return 1; } Else if (Value1 < value2) { return -1; } Else { return 0; }} var result = Compare (5,10);
1. Scope Chain:
The scope chain is created when the function is defined, and when the function needs to query the value of a variable, the JS parser goes to the scope chain to find it. In the above example, when I was found, I was looked up in function B, found then returned, not found to continue at the top level of the chain as function A, if not found, and then to the global chain to find, if not in the global chain, then return undefined.
When you create a function, a scope chain is created that contains the global variable object, which is stored in the internal [Scope] property. When a function is called, an execution environment is created for the function and then the scope chain of the execution environment is built from the object in the Copy function [[Scope]] property.
In the example above, for the execution environment of the Compare () function, its scope contains two variable objects: The local active object and the global variable object. A scope chain is essentially a pointer table to a variable object that references but does not actually contain a variable object.
When a variable is accessed in a function, a variable with the corresponding name is searched from the scope chain. In general, when the function is finished, the local active object is destroyed and only the global scope is saved in memory. But closures are also different.
2. Garbage collection mechanism:
A function, at the beginning of execution, divides the memory space of the variables defined therein to save the variables. Once the functions have been executed, the memory of these variables will be recycled. It will be reassigned again the next time it is executed.
If another function is nested inside a function, it is possible that the intrinsic function is called externally, and the intrinsic function uses some of the variables of the external function.
In this case, when the JS interpreter encounters a function definition, it automatically saves the function along with the variables it might use (including variables of local variables, parent and grandparent functions), which is to construct a closure.
These variables will not be reclaimed by the memory collector. This closure is only destroyed if the internal function is not possible to be called.
3. Closures and variables:
A closure can only get the last value that contains any variable in the function. A closure holds the entire variable object, not a particular variable.
var New Array (); function createfunctions () { for (var i=0; i<10; i++) { function () { return i; } } return result;} Createfunctions (); alert (result[0] ()); // Tenalert (Result[9] ()); // Ten
This function returns an array of functions, which, on the surface, seems to return its own index value for each function, but in practice, each function returns 10.
Because the active object of the Createfunctions () function is kept in the scope chain of each function, they refer to the same variable i. When the Createfunctions () function returns, the value of the variable i is 10,
At this point, each function refers to the same variable object that holds the variable i, so the value of I within each function is 10.
We can create another anonymous function that forces the behavior of the closure to match expectations.
varresult =NewArray ();functioncreatefunctions () { for(vari=0; i<10; i++) {Result[i]=function(num) {return function(){ returnnum; }} (i); } returnresult;} Createfunctions (); Alert (result[0] ());//0Alert (Result[9] ());//9
In the preceding code, the closure is not assigned directly to the array, but an anonymous function is defined, and the result of executing the anonymous function is assigned to the array immediately. The anonymous function here has a parameter num, which is the value to be returned by the final function. When we call the anonymous function, we pass in the parameter I. Because the function parameter is passed by value, the value of the variable i is copied to the parameter num. Inside this anonymous function, the closure of NUM is created and returned. In this way, each function of the result array has its own copy of the NUM variable, so you can return different values.
4. About this object:
The use of this object in closures can also cause some problems. The This object is bound at run time based on the execution environment of the function: in the global function, this equals window, and when the function is called as a method of an object, this is equal to the current object. However, the execution environment of an anonymous function is global, so its this object usually points to window. But sometimes, because of the way closures are written, this may not be so obvious:
var name = "the window"; var object = { "My object", function() { return function () { this. Name;};} ; Alert (Object.getnamefunc () ()); // The Window
The above code first creates a global variable name and creates an object that contains the Name property. This object also contains a method--getnamefunc (), which returns an anonymous function, and the anonymous function returns THIS.NAME. Because Getnamefunc () returns a function, calling Object.getnamefunc () () invokes the function it returns immediately, and the result is a string returned. However, this result is the value of the global name variable "the window".
When each function is called, its active object automatically gets two special variables: this and arguments. When the intrinsic function searches for these two variables, it only searches for its active object, so it is never possible to directly access these two variables in the external function. However, the this object in the outer scope is stored in a variable that can be accessed by a closure, allowing the closure to be accessed by the enclosing packet.
var name = "The window" ; var object = {name: " My object ", Getnamefunc: function () {
var that =
this
;
return
function
() {
return
That.name; }; }};alert (Object.getnamefunc ());
//
my Object
Before you define an anonymous function, assign the This object to a variable named that. Closures can also be accessed by the closure after the closure has been defined. Even after the function returns, that is still referencing Object, so calling Object.getnamefunc () () returns "My object".
JS function expression--closure