The opening
Scopes are one of the most important foundations of any computer language, so scopes and scope chains are an inescapable topic if you want to learn JavaScript in depth.
As mentioned in Exploring JS — Execution Context Stack, when JavaScript code executes a executable code, an execution context is created.
For each execution context, there are three important properties:
- Variable Object (VO)
- Scope chain
- this
Today we’re going to focus on scope chains.
scope
Before going into scope chain, we will talk about scope first. Simply put, scope is the accessible scope of variables and functions, that is, scope controls the visibility and life cycle of variables and functions.
In JavaScript, there are two types of scope for variables: global scope and local scope (also known as function scope).
The scope chain
When the code looks for a variable, it first looks for the variable object of the current context. If it does not find one, it looks for the variable object of the execution context from the parent (lexical parent) until it finds the variable object of the global context, which is the global object.
Scoping can be explained by saying:
The rule for traversing the scope chain is simple: the engine looks for a variable starting at the current execution scope. If it can’t find one, the search continues up one level. When it reaches the outermost global scope, the search is stopped whether it was found or not.
Thus a linked list of variable objects in multiple execution contexts is called a scoped chain.
Let’s take a look at how scope chains are created and changed in two phases, the creation and activation of a function.
Function creates
The scope of a function is determined at the time the function is defined — that is, JavaScript uses static scope.
This is because the function has an internal property [[scope]], into which all parent objects are stored when the function is created. You can understand that [[scope]] is the hierarchy of all parent objects, but note that [[scope]] does not represent the full scope chain!
Here’s an example:
function foo(){
function bar(){... }}Copy the code
When a function is created, its respective [[scope]] is:
foo.[[scope]] = [
globalContext.VO
];
bar.[[scope]] = [
fooContext.AO,
globalContext.VO
];
Copy the code
Function is activated
When a function is activated, the active object is added to the front of the action chain after the VO/AO is created in the function context.
The Scope chain of the execution context is called Scope:
Scope = [AO].concat([[Scope]]);
Copy the code
At this point, the scope chain is created.
Understand deeply by examples
Creating a scope chain and a variable object in the context of a function execution can be summarized as follows:
var scope = "global scope";
function checkscope(){
var scope2 = 'local scope';
return scope2;
}
checkscope();
Copy the code
The execution process is as follows:
1. The checkScope function is created to save the scope chain to the inner property [[scope]];
checkscope.[[scope]] = [
globalContext.VO
];
Copy the code
2. Execute the checkScope function, create the checkScope function execution context, the checkScope function execution context is pushed into the execution context stack;
ECStack = [
checkscopeContext,
globalContext
];
Copy the code
Create a scope chain by copying the [[scope]] property of the function.
checkscopeContext = {
Scope: checkscope.[[scope]],
}
Copy the code
Step 2: Use arguments to create the active object, and then initialize the active object by adding parameters, function declarations, and variable declarations.
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope2: undefined, Scope: checkScope.[[Scope]],}Copy the code
Step 3: Press the active object into the top of the CheckScope chain.
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope2: undefined
},
Scope: [AO, [[Scope]]]
}
Copy the code
6. After the preparation, execute the function. As the function is executed, modify the AO attribute value.
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope2: 'local scope'
},
Scope: [AO, [[Scope]]]
}
Copy the code
7. The value of scope2 is found, and the function context is ejected from the execution context stack.
ECStack = [
globalContext
];
Copy the code
Reference:
JavaScript Deep Chain of scopes
An Inside look at JavaScript, starting with scope chains
Learn more about the JavaScript catalog
- #1 [In-depth study of JS — Prototype and Prototype Chain]
- #2: Lexical scope and dynamic scope
- #3 [In-depth study of JS — implement Yamashita Text stack]
- #4 【 In-depth study of JS – variable objects 】
- #5 [In-depth study of JS — scope chain]
- #6 [In-depth study of JS — This point in real Development Scenarios]
- #7: The execution context of JS
- #8: Js closures
- #9 — Parameter passing by value
- Class array objects and arguments
- Learn more about the various ways to create objects in JS
Welcome to add my personal wechat to discuss technology and personal growth.