Objective
In the context of execution, it is said that when JavaScript code executes a piece of executable code, it creates the corresponding execution context (execution context).
- Variable object (Variable object,vo)
- Scope chain (scope chain)
- This
Lexical scopes
In the scope, it is said that JavaScript uses lexical scopes, also known as static scopes, which are determined when the function is compiled (compiled in a short time before JS execution), not when the function is called;
This is because functions (a function is an instance of function, which is written later) have an internal property [[scope]], and when the function is compiled, all the parent variable objects are saved in the internal property [[scope]], you can understand [[scope]] Is the hierarchical chain of all parent variable objects, but note: [[scope] does not represent a complete scope chain!
Note: Although JS is the browser to interpret the execution, but JS is also the existence of compilation (computer only know the binary where you write the ABCD), and only with the Java. NET and other languages a little different, specifically can see "You do not know Javadcript", roll up, lexical scope This is also a detailed explanation;
Scope chain
In the derivation chain, the essence of the scope chain is a pointer linked list that points to the variable object.
When looking for a variable, it is looked up from the variable object in the current context, and if it is not found, it is found in the variable object that executes the context from the parent (the parent at the lexical level), and the variable object, which is the global context, is located, that is, the global object. The list of variable objects that are composed of multiple execution contexts is called a scope chain.
Here's an example of how the scope chain is built:
1 vara=10;2 functionrun () {3 varName= ' Joel ';4 functionsay () {5 varcontent= ' Hello ', name= ' Word ';6 7Console.log (content+name+ ', ' +a);8 }9 say ();Ten } OneRun ();//Hello word,10
Post-compilation function internal properties
// compile-time respective [[scope]] Run. [[scope]] = [ // global Variable object ]; = [ run. VO, Globalcontext.vo];
Execute function
function execution is divided into two parts
- Create a Context object
- Code execution
Create a context object, create a Vo variable object, scope chain scope chain, this pointer, and copy the value of the function object's internal property [[scope]] to the context object scope chain property
run.ec={ vo:{ // Variable object initialization }, //scope chain:run.[ [Scope], scope Chain:globalContext.VO, this: Thisvalue}
Execution phase At this time the context is pushed into the environment stack, VO activation for AO, when VO has been initialized to complete, at this time the current environment of AO is inserted into the scope chain top
That is, Scope = Ao+[[scope]]
The AO is added at the front of the scope chain
Scope = [Ao].concat ([[Scope]])
function Start Execution phase
// Execute run.ec={ ao:{ / / Variable object initialization }, // scope Chain:ao+run. [[Scope], scope chain:ao+globalcontext.vo, this: Thisvalue}
Scope chain = (dynamic) active object (AO) + (Static) Scope property
Moving refers to the variable object at the time of execution, static refers to the lexical scope, that is, the parent variable object;
Create a process
In the example below, we summarize the creation of the scope chain in the context of the function execution by combining the previous execution context, the variable object, and the execution context stack:
1 var scope = "global scope"; 2 function Checkscope () {3 var scope2 = ' local scope '; 4 return scope2; 5 }6 checkscope ();
The execution process is as follows:
1.checkscope function is created/compiled, save parent variable object to internal property [[scope]]
Checkscope. [[scope]] = [ globalcontext.vo];
2. Execute Checkscope function, do not immediately execute, JS internal start to prepare, create context object, push into execution environment stack
Checkscopecontext ={}
First step: Create a scope chain for the context object: Copy function internal properties [[scope]] to create a scope chain
Checkscopecontext = { scope:checkscope.[ [Scope],}
Step Two: Create a context Variable object: Start with arguments to initialize the variable object, the value is the default value undefined, continue to initialize the function, var variable
Checkscopecontext = { AO: { arguments: { 0 }, scope2:undefined }, Scope: Checkscope. [[Scope]],}
Step three: Bind this pointer variable object initialization is complete, start executing function, Vo is active as AO
3. Completion of preparation, start of function execution
Executes the Checkscope function, the Checkscope function execution context object is pressed into the execution context stack
Ecstack = [ checkscopecontext, Globalcontext];
4.VO activates into AO, pressing the active object into the top of the checkscope scope chain
Checkscopecontext = { AO: { arguments: { length:0 }, scope2:undefined }, Scope : [AO, [[Scope]]}
5. With function execution, modify the properties value of AO
Checkscopecontext = { AO: { arguments: { 0 }, ' local scope ' }, Scope: [AO, [[Scope]]}
6. Find the value of scope2, return after function execution, function context from the execution context stack Popup
Ecstack = [ globalcontext];
Summarize
When parsing code, be sure to look back at the definition of the function, after all, the lexical scope.
The function Scope chain = (moving) The active object (AO) + (Static) scope
property .
JavaScript's scope chain-10