Home >Web Front-end >JS Tutorial >JavaScript scope chain part 2: function life cycle
The life cycle of a function is divided into creation and activation phases (when called), let us study it in detail.
Function Creation
As we all know, function declaration is put into variable/activity (VO/AO) object when entering context. Let's look at the variable and function declarations in the global context (here the variable object is the global object itself, we remember that, right?)
var x = 10; function foo() { var y = 20; alert(x + y); } foo(); // 30
On function activation, we get the correct (expected) result - 30 . However, there is one very important feature.
Previously, we only talked about variable objects related to the current context. Here, we see that the variable "y" is defined in the function "foo" (meaning it is in the AO of the foo context), but the variable "x" is not defined in the "foo" context, and accordingly, it does not Added to the AO of "foo". At first glance, the variable "x" does not exist at all relative to the function "foo"; but as we see below - and only at a "glance", we find that the active object of the "foo" context only contains one Attribute - "y".
fooContext.AO = { y: undefined // undefined – 进入上下文的时候是20 – at activation };
How does function "foo" access variable "x"? In theory, the function should be able to access the variable object of a higher-level context. In fact, it is exactly like this. This mechanism is implemented through the [[scope]] attribute inside the function.
[[scope]] is the hierarchical chain of all parent variable objects, which is above the current function context and is stored in it when the function is created.
Note this important point - [[scope]] is stored when the function is created - static (immutable), forever and ever, until the function is destroyed. That is: the function can never be called, but the [[scope]] attribute has been written and stored in the function object.
Another thing to consider is that - compared with the scope chain, [[scope]] is an attribute of the function rather than the context. Considering the above example, the [[scope]] of function "foo" is as follows:
foo.[[Scope]] = [ globalContext.VO // === Global ];
For example, we use the usual ECMAScript arrays to represent the scope and [[scope]].
Continuing, we know that the context is entered when the function is called. At this time, the active object is created, and this and the scope (scope chain) are determined. Let us consider this moment in detail.
Function activation
As mentioned in the definition, after entering the context to create AO/VO, the Scope attribute of the context (a scope chain for variable search) is defined as follows:
Scope = AO|VO + [[Scope]]
The meaning of the above code is: active object Is the first object in the scope array, that is, the front end added to the scope.
Scope = [AO].concat([[Scope]]);
This feature is very important for the processing of identifier parsing. Identifier resolution is the process of determining which variable object a variable (or function declaration) belongs to.
In the return value of this algorithm, we always have a reference type, its base component is the corresponding variable object (or null if not found), and the attribute name component is the name of the identifier looked up. Details of reference types are discussed later.
The identifier resolution process includes the lookup of the attributes corresponding to the variable names, that is, the continuous lookup of the variable objects in the scope, starting from the deepest context, bypassing the scope chain to the top level.
In this way, in upward search, local variables in a context have higher priority than variables in the parent scope. In case two variables have the same name but come from different scopes, the first one found is in the deepest scope.
We use a slightly more complicated example to describe what we have mentioned above.
var x = 10; function foo() { var y = 20; function bar() { var z = 30; alert(x + y + z); } bar(); } foo(); // 60
For this, we have the following variables/activities, the [[scope]] attribute of the function and the scope chain of the context:
The variable object of the global context is:
globalContext.VO === Global = { x: 10 foo: <reference to function> };
When "foo" is created, The [[scope]] attribute of "foo" is:
foo.[[Scope]] = [ globalContext.VO ];
When "foo" is activated (enters the context), the active object of the "foo" context is:
fooContext.AO = { y: 20, bar: <reference to function> };
The scope chain of the "foo" context is:
fooContext.Scope = fooContext.AO + foo.[[Scope]] // i.e.: fooContext.Scope = [ fooContext.AO, globalContext.VO ];
When the internal function "bar" is created, its [[scope]] is:
bar.[[Scope]] = [ fooContext.AO, globalContext.VO ];
When "bar" is activated, the active object of the "bar" context is:
barContext.AO = { z: 30 };
The scope chain of the "bar" context is:
barContext.Scope = barContext.AO + bar.[[Scope]] // i.e.: barContext.Scope = [ barContext.AO, fooContext.AO, globalContext.VO ];
The identifiers of "x", "y", and "z" are analyzed as follows:
- "x" -- barContext.AO // not found -- fooContext.AO // not found -- globalContext.VO // found - 10 - "y" -- barContext.AO // not found -- fooContext.AO // found - 20 - "z" -- barContext.AO // found - 30
The above is the second part of the JavaScript scope chain: the content of the life cycle of the function. For more related content, please pay attention to the PHP Chinese website (www .php.cn)!