Introduction in programming, we usually define functions and variables to successfully construct our system. But how does the parser find the data (functions, variables? What happened when we reference the desired object? Many ECMAScript programmers know that variables are closely related to the execution Context Environment: Copy code 1 var a = 10; // variable 2 (function () in the Global Context Environment () {3 var B = 20; // local variable 4} in the context of the function) (); 5 alert (a); // 106 alert (B ); // "B" does not define the replication code. Of course, many programmers know it. In the current standard version, the isolated scope can only be generated by the execution context of the "function" code. Unlike c/c ++, for example, the for loop statement block in ECMAScript cannot generate a local execution context: 1 for (var k in {a: 1, B: 2 }) {2 alert (k); 3} 4 alert (k); // even if the loop ends, let's take a look at the variable 'K' in the scope, more details occur when we declare our data. Data declaration if the variables are closely related to the execution context, You should know where the data is stored and how to obtain the data. This mechanism is called a variable object. A variable object (VO) is a special object closely related to the execution context and its storage location: variables (var, variable Declaration), function declaration (FD), and function parameters; declared in the context. Note that the lexical environment mode replaces variable objects in ec5. Theoretically, the variable object can be represented as a general ECMAScript object: VO ={}; as we said, VO is an attribute of the execution context: 1 activeExecutionContext = {2 Vo: {3 // Context Data (var, FD, function arguments) 4} 5}; Generally, variables cannot be referenced directly. Only variables in the global context can be referenced (through the VO attribute name) (the Global object is its own variable object ). It is impossible for other execution contexts to directly reference VO. It is only a pure mechanism at the implementation level. When we declare a variable or function. In addition to constructing VO attributes that contain variable names and variable values, we have nothing to do with it. For example, var a = 10; function test (x) {var B = 20 ;}; test (30); the corresponding variable object is: copy code 1 // The variable object 2 VO (globalContext) in the global environment = {3 a = 10, 4 test: <reerence to function> 5 }; 6 // variable object of the "test" function context 7 VO (test functionContext) = {8 x: 30, 9 B: 2010 }; copying code, but in the execution stage (standard), variable objects are an abstract nature. In the specific execution context, VO has different naming methods and different initial structures. Some operations (such as variable assignment) and actions of variable objects in different execution contexts are the same in all execution context types. From this perspective, it is very convenient to represent a variable object as an abstract basic concept. Function context can also define additional information related to variable objects. Copy code 1 AbstratVO (general process of variable Object Instantiation) 2 ← 3 ←> globalcontext_4 ← (VO === this === global) 5. 6. Copying code> FunctionContextVO7 (VO = AO, <arguments> object and <formal parameters> are added) let's discuss it in detail. The global context variable object should first be defined as a Global Object: A Global object is an object that has been constructed before it enters any execution context; the global object is unique (Note: Singleton mode), and its attributes can be obtained anywhere in the program. its lifecycle ends with the end of the program. The constructed global object is initialized by attributes such as Math, String, Date, and parseInt. You can also use some additional objects that can reference the global object itself for initialization. For example, in BOM, the window attribute of the global object points to the global Object (however, not all implementations are like this). Copy code 1 global = {2 Math: <...>, 3 String: <...>, 4 .... 5 .... 6 window: global7}; copy the code. When the Global Object attribute is referenced, the prefix is usually omitted because the global object cannot be obtained directly by name. It may be obtained through the value this in the global context, or by reference it recursively. For example, the window in BOM can be abbreviated as: 1 String (10); // indicates global. string (10); 2 // a prefix of 3 windows. a = 10; // = global. window. a = 10 = global. a = 10; 4 this. B = 20; // global. B = 20. Therefore, return to the variable object in the global context-the variable object here is the global object itself: VO (globalContex) = global; in view of these reasons, you must understand this fact accurately: a variable declared in the global context can be referenced indirectly through the attributes of the Global Object (for example, the variable name is unknown). Copy code 1 var a = new String ('test ') 2 alert (a); // direct reference, in VO (globalCOntext): "test" 3 alert (window ['a']); // indirect reference = = VO (globalContext): "test" 4 alert (a = this. a); // true5 var akey = 'a'; 6 alert (window [akey]); // indirect reference by dynamic attribute name: the variable object that copies the code function context cannot be directly obtained for the function execution context-VO. Its role is played by the active object (AO. VO (functionContext) = AO; When a function context is entered, an active object is generated. It is initialized by the Arguments attribute of the arguments object. 1 AO = {arguments: <Arguments Object>} the Arguments Object is the attribute of the activity Object. It contains the following attributes: callee -- reference of the function itself; length -- number of real arguments; properties-indexes (integer, converted to a character ), the value is the value of the function parameter (from left to right of the parameter list ). Properties-indexes = arguments. length. that is, the properties-indexes value of the parameter object and the current (actual input value) parameter are the shared copy code 1 function foo (x, y, z) {3 // number of defined function parameters (x, y, z) 4 alert (foo. length); // 3 6 // The actual parameter quantity (only x, y) 7 alert (arguments. length); // 29 // reference 10 alert (arguments. callee = foo); // true12 // The parameter shares 14 alert (x = arguments [0]); // true15 alert (x ); // 1017 arguments [0] = 20; 18 alert (x); // 2020 x = 30; 21 alert (argumen Ts [0]); // 3023 // However, for z without passing parameters, the index attribute of the arguments parameter object is not shared 27 z = 40; 28 alert (arguments [2]); // undefined30 arguments [2] = 50; 31 alert (z ); // 4033} the parameter sharing vulnerability exists in the earlier google browser. In ec5. The concept of an active object has been replaced by the public and Singleton modes in the lexical environment. The process of context code is now the focus of the article. The process of execution context code is divided into two stages: the execution context and the Execution Code. The correction of variable objects is also closely related to these two stages. It should be noted that the processing process in these two stages is a general action and independent from the context type (that is, this process is equal for the execution context-functions and the global) when the execution context is entered (before the code is executed), VO is filled with the following attributes (they are mentioned earlier. For each form parameter of a function (if we have already entered the context of the function execution)-a variable object attribute containing the name and the value of the form parameter is created, the parameter has not yet passed a value-that is, the attribute containing the parameter name and its value is undefined is created. For each function declaration (FD), an attribute containing the name and value of the function object is created. If the variable object already contains an attribute of the same name, it overwrites its values and features; for each variable Declaration-an attribute containing the variable name and its value is undefined is created. If the variable name is the same as the declared parameter or function name, the variable declaration cannot conflict with an existing attribute (Translator's note: This variable name is not available, in other words ). Let's take a look at the following example. Copy the Code 1 function test (a, B) {2 var c = 10; 3 function d (){}; 4 var e = function _ e () {}; 5 (function x () {}); 6} 7 test (10) copy code when entering the context of the test function containing the real argument 10, AO is as follows: Copy code 1 AO (test) = {2 a: B: undefined, 4 c: undefined, 5 d: <reference to FunctionDeclaration "d"> 6 e: undefinedhttp: // I .cnblogs.com/EditPosts.aspx? Postid = 37119637}; copy the code. Note that this AO does not contain Function X because X is not a function declaration but a function expression (FE) and does not affect VO. Function _ e is also a function expression, but we will find it in VO because it is assigned to variable e, which is obtained through e. Function declarations and function expressions will be discussed in detail later. After these operations, the second stage of context code processing-code generation execution. At this time, AO/VO already contains these attributes (although not all attributes have the actual values passed, most of them already have the initial value undefined ). in the same example, AO/VO makes the following corrections during code parsing: 1 AO ['C'] = 10; 2 AO ['E'] = <reference to FunctionExpression "_ e">; note that this function expression _ e only exists in the memory, because it is saved in the declared variable e. However, the function expression x is not in AO/VO. If we call the x function before or after the definition, the error "x" is not defined. an unsaved function expression can only be called or recursively called at the place it is defined. A classic instance: copy the Code 1 alert (x) // function x () {} 2 var x = 10; 3 alert (x); // 10 4 x = 20; 5 function x () {} 6 alert (x); // 20 copy the code. Why is X a function popped up At the beginning and can be obtained before it is declared? Why not 10 or 20? Because, according to the rule-VO is filled by function declaration before entering the context. At the same time, here is a variable declaration x, but as we have mentioned above, the semantic variable declaration stage is after the function declaration and parameter declaration. During this period, the variable cannot conflict with the declared function and parameter name. Therefore, when entering the VO context: 1 VO ={}; 2 VO ['X'] = <reference to FunctionDeclaration "x"> 3 // var x = 10; 4 // if function "x" is not defined yet, and "x" is undefined. However, in this case, variable declarations cannot interfere with functions with the same name. 5 VO ['X'] = <the value is not damaged. If it is a function> In the code execution stage, the VO correction is as follows: 1 VO ['X'] = 10; 2 VO ['X'] = 20; the result we output in the second and third alert. In the following example, in the context stage, we can see that the variable is placed in VO (therefore, else is never executed, but even so, variable B still exists in VO ): copy code 1 if (true) {2 var a = 1; 3} else {4 var B = 1; 5} 6 alert (a); // 17 alert (B ); // undefined but not "B is not defined" copy the code. Many articles about the variable about javascript or even the book said: "Use the var keyword (in the global execution environment) and does not use the var keyword (anywhere) to declare a global variable ". This is not the case. Remember: variables can only be declared using the var keyword. Assign a value like this: a = 10; only new attributes (rather than variables) of the global object are created ). In this sense, "Not the variable" cannot be changed, but under the variable concept of ECMAScript (due to VO (globalContext) = global, what do we remember ?), It becomes a global object attribute. The difference is as follows (as shown in an example) 1 alert (a); // undefined2 alert (B); // B is not defined3 B = 10; 4 var a = 20; all dependent on VO and its correction phase (entering the execution context and code execution phase): Entering the context: 1 VO = {a: undefined }; we can see that there is no B at this stage, because it is not a variable. B only appears in the code execution phase (in this case, it will not be wrong ). The modified code is as follows: 1 alert (a); // undefined, we know why 3 B = 10; 4 alert (B); // 10, created at code execution 6 var a = 20; 7 alert (a); // 20, modified at code execution there is more important about the variable here. Variables are different from simple attributes. They have the {DontDelete} attribute, meaning that a variable cannot be deleted using the delete OPERATOR: copy the Code 1 a = 10; 2 alert (window. a); // 103 alert (delete a); // true4 alert (window. a); // undefined5 var B = 20; 6 alert (window. b); // 207 alert (delete B); // false8 alert (window. b); // still 20 copy the code. Remember: In ES5, {DontDelete} is renamed to [[Configureable], and can use Object. the defineProperty method is managed manually. However, this rule does not work in the context of execution. This is the EVAL context: the variable does not set the {DontDelete} attribute: 1 eval ('var a = 10; '); 2 alert (window. a); // 10 4 alert (delete a); // true 6 alert (window. a); // undefined for debugging tools that verify these examples on the console, such as firebug: Remember, firebug also uses eval on the console to execute your code. Therefore, these variables do not have the {DontDelete} attribute and can be deleted. Features of the Implementation Layer: We have noticed the _ parent _ attribute under standard conditions. It is impossible to directly obtain the activity object. However, in some implementations, such as SpiderMonkey and Rhino. A function has a special attribute _ parent _. It can reference the activity objects that have been generated in the function. Example (SpiderMonkey, Rhino): copy the Code 1 var global = this; 2 var a = 10; 3 function foo () {} 4 alert (foo. _ parent _); // global5 var VO = foo. _ parent _; 6 alert (VO. a); // 107 alert (VO = global); // copy the code in true. In the above example, we can see that the function foo () is constructed in the global context. Accordingly, the variable object whose _ parent _ attribute is set as the global context is also the global object. However, it is impossible for SpiderMonkey to obtain the active object in the same way: based on different versions, the _ parent _ of the internal function returns null or a global object. In Rhino, you can obtain activity objects in the same way: Copy code 1 var global = this; 2 var a = 10; 3 (function foo () {4 var y = 20; 5 // activity object of the "foo" function context 6 var AO = (function (){}). _ parent _; 7 alert (AO. y); // 20 8 // The _ parent _ of the current active object has become a global object. In this way, a special chain of variable objects is formed, that is, the so-called scope chain 9 alert (AO. _ parent _ = global); // true10 alert (AO. _ parent _. x); // 1011}) () copy the code summary. In this article, we continue to dive into the objects related to the execution context. I hope these materials are useful and clear some of the ambiguous aspects you have previously considered. In future plans, the scope chain will be discussed in the following sections, and the identifier will be determined, and the closure will eventually be used.