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, the scope chain of execution B contains 3 objects: The active object of B, the active object of a, and the Window object, as shown in:
, when a variable is accessed 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.
Reference: http://www.jb51.net/article/24101.htm
The microcosm within the "classic" closures