Home  >  Article  >  Web Front-end  >  Understanding Javascript_13_Detailed Explanation of Execution Model_Javascript Skills

Understanding Javascript_13_Detailed Explanation of Execution Model_Javascript Skills

WBOY
WBOYOriginal
2016-05-16 18:18:111049browse
Function execution environment
Simple code:
Copy code The code is as follows:

function say(msg,other){
var str = "nobody say:";
this.name = 'Idiot's motto';
function method(){};//var method = function(){};
alert(str msg);
}
say('hello world');
alert(name); // Idiot's motto

When calling the say method, the first step is to create its execution environment. In the process of creating the execution environment, a series of operations will be completed in the defined order:
1. First, an 'active object' will be created '(Activation Object). Active objects are another mechanism specified in the specification. It is called an object because it has accessible named properties, but it does not have a prototype like a normal object (at least not a predefined prototype), and the active object cannot be directly referenced through JavaScript code.
2. The next step in creating an execution environment for function calls is to create an arguments object, which is an array-like object that stores the parameters passed when calling the function in one-to-one correspondence with integer-indexed array members. This object also has length and callee properties (for more in-depth information, see "Understanding Javascript_14_Function Parameters and Arguments"). Then, a property called "arguments" is created for the active object, which references the arguments object created earlier.
3. Next, assign a scope to the execution environment. A scope consists of a list (chain) of objects. (It’s more complicated, please see: "Understanding Javascript_15_Scope Allocation and Variable Access Rules, and Send a Closure")
4. Afterwards, 'variable instantiation' completed by the so-called 'active object' in ECMA 262 will occur ( Variable Installation) process. At this time, the formal parameters of the function will be created as named properties of the variable object. If the parameters passed when calling the function are consistent with the formal parameters, the values ​​of the corresponding parameters will be assigned to these named properties (otherwise, the named properties will be assigned an undefined value ). For defined internal functions, a property of the same name is created on the mutable object with the name it was declared with, and the corresponding internal function is created as a function object and assigned to that property. The final step in variable instantiation is to create all local variables declared inside the function as named properties of the mutable object. Note: In this process, except for the actual parameters that have values ​​and the function definition, all others are 'pre-parsed' as undefined values.
5. Finally, a value must be assigned for using the this keyword. (This at this time points to the global object, that is, window)

After the execution environment is successfully created, enter the second step: execute the code from top to bottom in the function body.
1. When var str='nobody say' is executed, a process called 'calculation assignment expression' will occur. At this time, the value of key str in the active object will be set from undefined to 'nobody say: '.
2. When executing this.name='Idiot's motto', the attribute name will be added to the object as this and assigned the value as 'Idiot's motto'.
3. Then function innerMethod(){ };Finally execute 'alert(str msg) and output 'nobody say:hello world'.

The difference between function method(){} and var method = function(){}
Simple code:
Copy code The code is as follows:

function say(){
method01();//method01
method02();//error
function method01(){
alert('method01');
}
var method02 = function() {
alert('method02');
}
}
say();

Why does calling method method01 run normally, but calling method method02 reports an error?
First of all, you must clearly know that method01 is a function object, and method02 is a variable, which points to another function object. According to the content of the previous section, in the process of 'Variable Instatiation' completed by the 'Active Object', the function method01 is normally 'pre-parsed', and the variable method02 is parsed to an undefined value. When entering When it comes to executing the code, because method02 is called before it calculates the function expression, if undefined is used as a method call, an error will inevitably be reported. The solution is relatively simple, just put var method02=function(){...} before the call of method02() or define the function in the form of function declaration (function method(){...}) .
Note: Calculating function expression means that the program is executed until var method02 = function(){...}. method02 actually points to a function object at this time. Because during 'pre-parsing', method02 was only assigned to undefined.

Global execution environment (already discussed in "Execution Model Analysis", no more details)
In a page, a global execution environment is created when the JS code is loaded for the first time. The scope chain of the global execution environment actually consists of only one object, the global object (window). Before starting the execution of the JavaScript code, the engine will Create this Scope Chain structure. The global execution environment will also have a variable instantiation process, and its internal functions are regular top-level function declarations that involve most JavaScript code. Moreover, the global object is a mutable object during variable instantiation, which is why globally declared functions are global object properties. The same is true for globally declared variables. The global execution environment will use the this object to refer to the global object.

Note: Distinguish between the Activation Object in the 'Function Execution Environment' and the Variable Object in the Global Execution Environment. Variable Object is also called Activation Object (because there are some differences, so A new name is given in the specification to show the difference. In the global execution environment/Eval execution environment, it is called Variable Object, and in the function execution environment, it is called Activation Object).

Eval execution environment
The variable object (Variable Object) when building the Eval execution environment is the variable object (Variable Object) in the current execution context when eval is called. When the eval function is called in the global execution environment, its variable object (Variable Object) is the global object; when eval is called in the function, its variable object (Variable Object) is the function's activation object (Activation Object).
Copy code The code is as follows:

//Passed in FF2.0, IE7, Opera9. 25, Safari3.0.4
function fn(arg){
var innerVar = "variable in function";
eval(' ​​
var evalVar = "variable in eval";
document.write (arg "
");
document.write(innerVar "
");
');
document.write(evalVar);
}
fn("arguments for function");

The output result is:
arguments for function
variable in function
variable in eval
Note: The parameters and local variables of the function fn can be accessed in the eval call; the local variables defined in eval can also be accessed in the function fn, because their Variable Object is the same object.
When entering Eval Code execution, a new Scope Chain will be created, the content of which is exactly the same as the Scope Chain of the current execution context.

The final example
code is as follows:
Copy codeThe code is as follows:

var outerVar1="variable in global code";
function fn1(arg1, arg2){
var innerVar1="variable in function code";
function fn2() { return outerVar1 " - " innerVar1 " - " " - " (arg1 arg2); }
return fn2();
}
var outerVar2=fn1(10, 20);

The execution process is roughly as follows:
1. Initialize the Global Object, which is the window object, and the Variable Object, which is the window object itself. Create a Scope Chain object, assuming it is scope_1, which only contains the window object.
2. Scan the JS source code (read the source code, there may be a lexical and syntax analysis process), and you can get the defined variable names and function objects from the results. According to the scanning order:
2.1 Discover the variable outerVar1, add the outerVar1 attribute to the window object, the value is undefined;
2.2 Discover the definition of function fn1, use this definition to create a function object, and the Scope Chain passed to the creation process is scope_1 . Add the result to the window property, with the name fn1 and the value being the returned function object. Note that the internal [[Scope]] of fn1 is scope_1. Also note that the creation process does not perform special processing on the JS code in the function body. It can be understood that it only saves the scanning results of the JS code in the function body in the internal properties of the function object, and further processes it when the function is executed. This is key to understanding Function Code, especially Variable Instantiation in nested function definitions;
2.3 Discover the variable outerVar2, add the outerVar2 attribute to the window object, and the value is undefined;
3. Execute the outerVar1 assignment statement and assign the value is "variable in global code".
4. Execute function fn1 and get the return value:
4.1 Create an Activation Object, assuming it is activation_1; create a new Scope Chain, assuming it is scope_2, the first object in scope_2 is activation_1, and the second object is window object (taken from [[Scope]] of fn1, that is, the content in scope_1);
4.2 Process parameter list. Set the attributes arg1 and arg2 on activation_1 with values ​​10 and 20 respectively. Create the arguments object and set it, and set arguments as attributes of activation_1;
4.3 Perform a process similar to step 2 on the function body of fn1:
4.3.1 Discover the variable innerVar1, add the innerVar1 attribute on the activation_1 object, The value is undefine;
4.3.2 Discover the definition of function fn2, use this definition to create a function object, and the Scope Chain passed to the creation process is scope_2 (the Scope Chain of function fn1 is the content of the current execution context). Add the result to the attribute of activation_1, with the name fn2 and the value being the returned function object. Note that the internal [[Scope]] of fn2 is scope_2;
4.4 Execute the innerVar1 assignment statement and assign the value to "variable in function code".
4.5 Execute fn2:
4.5.1 Create an Activation Object, assuming it is activation_2; create a new Scope Chain, assuming it is scope_3. The first object in scope_3 is activation_2, and the following objects are activation_1 and window. Object (taken from [[Scope]] of fn2, that is, scope_2);
4.5.2 Process parameter list. Because fn2 has no parameters, just create the arguments object and set it as the attribute of activation_2.
4.5.3 Perform a process similar to step 2 on the function body of fn2, and no variable definitions and function declarations are found.
4.5.4 Execute function body. For any variable reference, search from scope_3. In this example, outerVar1 will be found on window; innerVar1, arg1, and arg2 will be found on activation_1.
4.5.5 Discard scope_3 and activation_2 (meaning they can be garbage collected).
4.5.6 Return the return value of fn2.
4.6 Discard activation_1 and scope_2.
4.7 Return results.
5. Assign the result to outerVar2.

Reference:
http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html
http://www .cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn