JavaScript Basic Learning-javascript authoritative guide--8.6 function closure

Source: Internet
Author: User

One, what is closures?

The official explanation is that closures are an expression (usually a function) that has many variables and environments that bind them, and so these variables are also part of the expression.
It is believed that very few people can read this sentence directly because he describes it as too academic.

In fact, the phrase is: All the function in JavaScript is a closed packet. In general, however, the nested function produces a more powerful closure, which is what we call "closures" most of the time. Look at the following code:

function a() {  var0;  function b() { alert(++i); }  return b;}var c = a();c();

There are two features of this code:

1. function b is nested inside function A;

2, function a returns function B.

So 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 (first 1). This code actually creates a closure, why? Because the variable C outside of function A refers to function B in function A, that is:

When function A's intrinsic function B is referenced by a variable outside of function A, a closure is created.

Let's talk a little more thoroughly. A "closure" is a method function that defines another function as the target object in the body of the constructor, and the method function of the object in turn refers to the temporary variable in the outer function body. This makes it possible to indirectly maintain the value of temporary variables used by the original constructor body as long as the target object retains its method throughout its lifetime. Although the initial constructor call has ended, the name of the temporary variable disappears, but the value of the variable is always referenced within the method of the target object, and the value can only be accessed through this method. Even if the same constructor is called again, but only new objects and methods are generated, the new temporary variable only corresponds to the new value, and the last time the call was separate.

What is the role of closures?

In short, the function of a closure is that after a executes and returns, the closure makes the garbage collection mechanism of the JavaScript GC does not reclaim the resources used by a, because the execution of the internal function B of a requires a dependency on the variables in a. This is a very straightforward description of the effect of closures, unprofessional and not rigorous, but the general meaning is that, understanding closures need a gradual process.

In the above example, because the existence of a closure causes function A to return, I in a always exists, so that every time C (), I is added 1 after the alert out of the value of I.

So let's imagine another situation where a returns a function B, which is completely different. Since a executes, B is not returned to the outside world of a, only a is referenced by a, and at this point a will only be referenced by B, so functions A and B are referenced by each other but are not disturbed by the outside world (referenced by the outside world), functions A and B will be collected by GC. (The garbage collection mechanism for JavaScript will be described in more detail later)

Third, the microcosm within the closures

To gain a deeper understanding of the relationship between closures and function A and nested function B, we need to introduce several other concepts: the function's execution environment (excution context), the active object (call object), scope (scope), scope chain (scope chain). Take function A from definition to execution as an example to illustrate these concepts.
When defining function A, the JS interpreter sets the scope chain of function A to the "environment" where a is located, and if a is a global function, only the window object is in scope chain.
When the function A is executed, a is entered into the appropriate execution environment (excution context).
During the creation of the execution environment, a scope property, the scope of a, is first added for a, and the value is the scope chain in step 1th. That is, the scope chain of the a.scope=a.
The execution environment then creates an active object (call object). The active object is also an object with properties, but it does not have a prototype and is not directly accessible through JavaScript code. After the active object is created, add the active object to the top of the scope chain of a. At this point A's scope chain contains two objects: A's active object and the Window object.
The next step is to add a arguments property on the active object, which holds the arguments passed when the function A is called.
Finally, the reference of all function A's parameters and internal function B is added to the active object of a. In this step, the definition of function B is completed, so as in the 3rd step, the scope chain of function B is set to the environment defined by B, which is the scope of a.

This completes the entire function A from definition to execution. At this point a returns a reference to function B to C, and the scope chain of function B contains a reference to the active object of function A, which means that B can access all the variables and functions defined in a. Function B is referenced by C and function B relies on function A, so function A is not recycled by GC after it returns.

When function B executes, it will be the same as the above steps. Therefore, at execution time, B's scope chain contains 3 objects: B's Active object, A's active object, and the Window object

When accessing a variable in function B, the search order is:
Searches for the active object itself first, if it exists, returns if there is no active object that will continue to search for function A, and then finds it until it is found.
If the prototype prototype object exists in function B, it finds its own prototype object after it finds its own active object, and then continues to look for it. This is the variable lookup mechanism in JavaScript.
Returns undefined if none of the entire scope chain is found.

Summary, two important words are mentioned in this paragraph: definition and execution of functions. It is mentioned in the article that the scope of the function is determined when the function is defined, not when it is executed (see steps 1 and 3).
In a piece of code,
function f (x) {
var g = function () {return x;}
return g;
}
var h = f (1);
Alert (H ());
The variable h points to the anonymous function in F (returned by G).
Assuming that the scope of the function h is determined by the execution alert (h ()), then the scope chain of H is: H's active object->alert the active object->window object.
Assuming that the scope of the function h is defined at the time of definition, the anonymous function pointed to by H has been scoped at the time of definition. Then, at execution time, the scope chain of H is: H's active object->f the active object->window object.

If the first hypothesis is true, the output value is undefined; if the second hypothesis is true, the output value is 1.

The result of the operation proves that the 2nd hypothesis is correct, stating that the scope of the function is indeed determined when the function is defined.

IV. implementation Environment and scope

4-1
The execution environment execution context, defines the other data that variables and functions have access to, and determines their respective behavior.
① Each execution environment has a variable object variable objects, which holds all the variables and functions defined by the environment. The object cannot be encoded for access, but the parser uses it in the background when it processes the data.
A global variable object is the outermost execution environment. is considered a window object in a Web browser, so all global objects and functions are created by properties and methods of the Window object.
After execution of the code in the execution environment, the environment is destroyed, and the variables and function definitions stored therein are destroyed.

When the ② code is executed in the environment, a scope chain of variable objects is created that is used to guarantee orderly access to all variables and functions that the execution environment has access to.
The scope chain front-end, which is always the variable object for the environment in which the code is currently executing. When the environment is a function, the active object is used as a variable object.
The active object initially contains only one variable, the Argumnt object.
The next variable object in the scope chain comes from the containing environment, and the next variable object comes from the next containment environment until it continues to the global execution environment.

③ Identifier parsing: The process of searching identifiers at the first level along the scope chain, starting with the previous paragraph. "Not found usually throws an exception to occur"

4-2. When the function is created and executed:

function compare(val1,val2){     if(val1<val2){        return -1;    }elseif(val1>val2){        return1;    }else{        return0;    };}var result = compare(510);
作用域链是定义函数时创建执行环境是调用函数时创建

When ① creates a function compare (), it creates a scope chain that pre-contains the global variable object and is saved in the internal [scope] property.
The variable object of ② local function compare () exists only in the process of function execution.
When a function is called, an execution environment is created and the scope chain of the execution environment is built from the object in the [scope] property of the copy function.
③ The first time a function is called, such as compare (), a live object that contains this, argument, Val1, and Val2 is created.
Variable objects ④ The global execution environment (including this, result, compare) are second in the scope chain of the Compare () execution environment.
The ⑤ scope chain essence is a pointer to a variable object list, referencing but not actually containing the variable object.
⑥ whenever a variable is accessed in a function, it searches for a variable with the corresponding name in the scope chain.

4-3. Scope chain of closures

A function defined inside another function adds the active object containing the function to its scope chain.
① assigns a Function object null, is equal to notifies the garbage collection routine to purge it, and its scope chain (except global scope) is safely destroyed as the function scope chain is destroyed.
② because closures carry a scope that contains functions, they consume more memory than other functions.

4-4. Closures and variables

A side effect of the scope chain: Closures can only get the last value of any variable in the containing function.

function  createfunctions   ()  { var  result = new  array  ()    ; for  (var  i=0 ; i < 10 ; i++) {Result[i] = function          ()  { return  i;    }; } return  result;}  

The

①createfunctions () function, assigns 10 closures to the array result, and returns the result array. Each closure returns its own index, but actually returns 10.
because the active object of the Createfunctions () function is stored in the scope chain of each function (closure), they refer to the same variable I, and when the Createfunctions function finishes executing the value of I 10, I in the closure is also 10.
② workaround, do not use closures, create an anonymous function, assign the I value to its parameters:

function  createfunctions   ()  { var  result = new  array  ()    ; for  (var  i=0 ; i < 10 ; i++) {Result[i] = function   { return  functi            On   ()  { return  num;        };    } (i); } return  result;}  

Create an anonymous function that executes once per loop: It is stored in an anonymous function by enclosing the I value of the function at each loop. Because function arguments are passed by value, not references, the NUM value in each anonymous function is a copy of the I value for each of these loops.

4-3.this Object

The This object is bound at run time based on the execution environment of the function.
In the global function, this is equal to window, and when the function is called by an object, this is the object.
The execution environment of an anonymous function is global, and its this object is usually referred to as window. When the function execution environment is changed by call () or spply (), this points to its object.
① each function will automatically get two special variables when it is called: this and argument. When the intrinsic function searches for these two variables, it will never be possible to access the two variables of the external function until the expired active object is searched.
However, keeping the this object of the outer scope in a variable accessible by a closure allows the closure to access the object.

The This object for the closure access external function

var"The Window";var object = {    "My Object",    function(){        varthis;        returnfunction(){            return that.name;        };    }};alert(object.getNameFunc()());  //"MyObject"

The argument object enclosing the function can also be accessed by the closure by this method.

JavaScript Basic Learning-javascript authoritative guide--8.6 function closure

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.