Deep understanding of the JavaScript series (12) Variable object (Variable object) _javascript Tips

Source: Internet
Author: User
Tags function definition
JavaScript programming always avoids the inevitable declaration of functions and variables to successfully build our system, but how and where do the interpreters look for these functions and variables? What exactly happened when we quoted these objects?
Original release: Dmitry A. Soshnikov
Release time: 2009-06-27
Russian address: http://dmitrysoshnikov.com/ecmascript/ru-chapter-2-variable-object/
English translation: Dmitry A. Soshnikov
Release time: 2010-03-15
English Address: http://dmitrysoshnikov.com/ecmascript/chapter-2-variable-object/
Some sentences that are difficult to translate refer to the Chinese translation of JUSTINW.
Most ECMAScript programmers should know that variables are closely related to the execution context:
code as follows:

var a = 10; Variables in the global context
(function () {
var B = 20; Local variables in a function context
})();
alert (a); 10
alert (b); global variable "B" has no declaration

Also, many programmers know that the current ECMAScript specification indicates that a stand-alone scope can only be created through the execution context of the function code type. In other words, the For loop in the ECMAScript does not create a local context relative to C + +.
 code as follows:

For (var k in {a:1, b:2}) {
Alert (k);
}
Alert (k); Although the Loop has ended but the variable k is still in the current scope

Let's take a look at the details of what we found when we declared the data.
Data declaration
If the variable is related to the execution context, the variable should know where its data is stored and know how to access it. This mechanism is called variable objects (variable object).
A Variable object (abbreviated to VO) is a special object that is related to the execution context, which stores the following content declared in the context:
Variable (var, variable declaration);
function declaration (functiondeclaration, abbreviated as FD);
The formal parameters of a function
For example, we can represent a variable object with a normal ECMAScript object:
 code as follows:

VO = {};
As we have said, Vo is the property of the execution context:
Activeexecutioncontext = {
VO: {
Contextual data (Var, FD, function arguments)
}
};

Only variable objects in the global context allow indirect access through the attribute name of VO (because in the global context, the global object itself is the variable object, which is described later), it is not possible to access the Vo object directly in other contexts because it is only an implementation of the internal mechanism.
When we declare a variable or a function, it is no different from the time we created the new attribute of Vo (that is, the name and the corresponding value).
For example:
 code as follows:

var a = 10;
function test (x) {
var B = 20;
};
Test (30);

The corresponding variable objects are:
 code as follows:

Variable object for global context
VO (Globalcontext) = {
A:10,
Test: <reference to Function>
};
Variable object for test function context
VO (Test Functioncontext) = {
X:30,
B:20
};

Variable objects are only an abstract concept at the concrete implementation level (and in the specification). (In essence, the VO name is not the same in the context of the specific execution, and the initial structure is different.)
Variable objects in different execution contexts
For all types of execution contexts, some operations of a variable object, such as variable initialization, and behavior are common. From this point of view, it is easier to understand variable objects as abstract basic things. Also defines additional content related to variable objects in the function context.
 code as follows:

Abstract Variable Object VO (general behavior of the variable initialization process)

╠══> Global Context Variable object Globalcontextvo
║ (VO = = This = = Global)

╚══> function Context Variable object Functioncontextvo
(VO = = AO, and added <arguments> and <formal parameters>)

Let's take a look at the details:
Variable objects in the global context
First, we want to give the global object a clear definition:
A global object is an object that has been created before any execution context is entered;
This object only exists, its properties can be accessed anywhere in the program, and the lifecycle of the global object terminates at the moment the program exits.

The global object Initial creation phase initializes the properties of math, String, Date, parseint, and so on, as well as additional objects created as attributes (which can point to the global object itself). For example, in the DOM, the window property of the global object can refer to the global object itself (not all implementations are, of course):
 code as follows:

Global = {
Math: <...>
String: <...>
...
...
Window:global//quote Self
};

Prefixes are usually ignored when accessing properties of global objects, because global objects cannot be accessed directly by name. However, we can still access the global object through this in the global context, as well as recursively referencing itself. For example, window in the DOM. To sum up, the code can be abbreviated as:
 code as follows:

String (10); Is global. String (10);
With a prefix
WINDOW.A = 10; = = = GLOBAL.WINDOW.A = = = 10 GLOBAL.A
this.b = 20; global.b = 20;

So, back to the variable object in the global context--where the variable object is the global object itself:
VO (globalcontext) = = Global;
It is very necessary to understand the above conclusion, based on this principle, in the global context of the Declaration of the corresponding, we can indirectly through the global object's properties to access it (for example, do not know the variable name beforehand).
 code as follows:

var a = new String (' Test ');
alert (a); Direct access, found in Vo (globalcontext): "Test"
Alert (window[' a ']); Indirect access through global: global = = VO (globalcontext): "Test"
Alert (A = = = THIS.A); True
var akey = ' a ';
Alert (Window[akey]); Indirect access through dynamic property names: "Test"

Variable objects in the context of a function
In the context of function execution, VO is not directly accessible, at which point the active object (Activation object, abbreviated to AO) plays the role of Vo.
VO (functioncontext) = = AO;
The active object is created at the moment of entering the function context, and it is initialized by the arguments property of the function. The value of the arguments property is the arguments object:
 code as follows:

AO = {
Arguments: <ArgO>
};

The arguments object is an attribute of the active object, which includes the following properties:
Callee-a reference to the current function
length-the number of parameters that are actually passed
The value of the Properties-indexes (integer of String type) property is the parameter value of the function (arranged from left to right by argument list). The number of internal elements in the properties-indexes is shared between the value of Arguments.length. Properties-indexes and the arguments actually passed in.
For example:
 code as follows:

function foo (x, y, z) {
Number of function arguments declared arguments (x, y, z)
alert (foo.length); 3
Number of arguments actually passed in (only X, y)
alert (arguments.length); 2
The callee of the parameter is the function itself
Alert (Arguments.callee = = foo); True
Parameter sharing
Alert (x = = = Arguments[0]); True
alert (x); 10
Arguments[0] = 20;
alert (x); 20
x = 30;
Alert (arguments[0]); 30
However, the parameter z is not passed in, and the 3rd index value of the parameter is not shared
z = 40;
Alert (arguments[2]); Undefined
ARGUMENTS[2] = 50;
alert (z); 40
}
Foo (10, 20);

The code for this example, in the current version of the Google Chrome browser, has a bug-that is still shared even if no parameters are passed Z,z and arguments[2].
2 stages of processing context code
Now we are finally at the core of this article. The code for the execution context is divided into two basic phases to process:
Enter execution context
Executing code
Changes in variable objects are closely related to these two phases.
Note: The processing of these 2 phases is a general behavior, independent of the type of the context (that is, the performance is the same in the global context and in the context of the function).
Enter execution context
When entering the execution context (before the code executes), VO already contains the following attributes (previously stated):
All parameters of the function (if we are in the function execution context)
-the properties of a variable object consisting of a name and corresponding value are created, and if no corresponding parameter is passed, the properties of a variable object consisting of a name and a undefined value are also created.
All function declarations (functiondeclaration, FD)
-the property of a variable object consisting of a name and a corresponding value (a function object (Function-object)) is created, and if the variable object already has a property of the same name, the property is completely replaced.
All variable declarations (VAR, variabledeclaration)
-the property of a variable object consisting of a name and a corresponding value (undefined) is created, and if the variable name is the same as a declared formal parameter or function, the variable declaration does not interfere with such a property that already exists.
Let's look at an example:
 code as follows:

function Test (A, b) {
var C = 10;
Function d () {}
var e = function _e () {};
(function X () {});
}
Test (10); Call

When entering the context of the test function with parameter 10, AO behaves as follows:
 code as follows:

AO (Test) = {
A:10,
B:undefined,
C:undefined,
D: <reference to Functiondeclaration "D" >
e:undefined
};

Note that AO does not contain the function "X". This is because "x" is a function expression (functionexpression, abbreviated to FE) rather than a function declaration, and the function expression does not affect VO. In any case, the function "_e" is also a function expression, but as we will see below, because it is assigned to the variable "E", it can be accessed by the name "E". The difference between the function declaration functiondeclaration and the function expression Functionexpression, will be discussed in detail in the 15th chapter functions, also can refer to the 2nd Chapter of this series to uncover the name function expression to understand.
After that, you go to the second stage of processing the context code-code execution.
Code execution
Within this cycle, AO/VO already owns the attribute (however, not all attributes have a value, the value of most properties or the system default initial value undefined).
Or the previous example, Ao/vo was modified during the interpretation of the code as follows:
code as follows:

Ao[' C '] = 10;
Ao[' e '] = <reference to Functionexpression "_e" >;

Note again that because functionexpression "_e" is saved to the declared variable "E", it still exists in memory. and functionexpression "X" does not exist in Ao/vo, that is to say, if we want to try to invoke the "X" function, there will be an error "X is not defined", whether before or after the function definition. An unsaved function expression can be invoked only in its own definition or recursion.
Another classic example:
 code as follows:

alert (x); function
var x = 10;
alert (x); 10
x = 20;
function X () {};
alert (x); 20

Why is the return value of the first alert "X" a function, and does it still have access to "X" before the "x" declaration? Why not 10 or 20? Because, according to the canonical function declaration, it is filled in when the context is entered; consent cycle, there is also a variable to declare "x" when entering the context, and as we said in the previous stage, the variable declaration follows the function declaration and the formal parameter declaration in order, and in this entry context stage, A variable declaration does not interfere with a function declaration or formal parameter declaration that already exists in Vo, and therefore, when entering the context, the structure of VO is as follows:
 code as follows:

VO = {};
vo[' x '] = <reference to Functiondeclaration "X" >
Find var x = 10;
If the function "X" is not already declared,
At this point, the value of "X" should be undefined.
But in this case, the variable declaration doesn't affect the value of a function with the same name.
vo[' x '] = <the value is not disturbed, still function>

Immediately thereafter, in the execution code phase, VO makes the following modifications:
 code as follows:

vo[' x '] = 10;
vo[' x '] = 20;

We can see this effect on the second to third alert.
In the following example we can see again that a variable is placed in VO in the context phase. (Because, although else part of the code will never execute, the variable "B" still exists in Vo anyway.) )
 code as follows:

if (true) {
var a = 1;
} else {
var B = 2;
}
alert (a); 1
alert (b); Undefined, not b no statement, but the value of B is undefined

About variables
Often, various articles and JavaScript-related books claim that "a variable can be declared either by using the VAR keyword (in the global context) or by not using the VAR keyword (anywhere)." Keep in mind that this is the wrong concept:
At any time, a variable can be declared only by using the var keyword.
The assignment statement above:
A = 10;
This simply creates a new attribute for the global object (but it is not a variable). "Not a variable" is not to say that it cannot be changed, but that it does not conform to the concept of variables in the ECMAScript specification, so it is "not a variable" (it can be a property of the global object, entirely because of vo (globalcontext) = = Global, do you remember this? )。
Let's look at the specific differences in the following example:
 code as follows:

alert (a); Undefined
alert (b); "B" has no statement
b = 10;
var a = 20;

All root causes are still VO and enter the context phase and code execution phase:
Enter the context phase:
 code as follows:

VO = {
a:undefined
};

As we can see, because "B" is not a variable, there is no "B" at this stage, and "B" will only appear in the Code execution phase (but in our case, it has gone wrong).
Let's change the example code:
 code as follows:

alert (a); Undefined, this is known to all,
b = 10;
alert (b); 10, code Execution phase creation
var a = 20;
alert (a); 20, Code Execution Phase modification

There is also an important point of knowledge about variables. Variables have an attribute: {dontdelete}, which means that the variable property cannot be deleted directly with the delete operator, as opposed to a simple property.
 code as follows:

A = 10;
alert (WINDOW.A); 10
Alert (delete a); True
alert (WINDOW.A); Undefined
var B = 20;
alert (WINDOW.B); 20
Alert (delete b); False
alert (WINDOW.B); Still 20

But the rule does not get out of context, that is the eval context, and the variable does not have the {Dontdelete} attribute.
 code as follows:

Eval (' var a = 10; ');
alert (WINDOW.A); 10
Alert (delete a); True
alert (WINDOW.A); Undefined

When you test the instance using a console of some debugging tools (for example, Firebug), be aware that Firebug also uses eval to execute your code in the console. Therefore, the variable property also has no {Dontdelete} attribute and can be deleted.
Special implementations: __PARENT__ properties
As mentioned earlier, in the standard specification, the active object is not directly accessible. However, some specific implementations do not fully comply with this provision, such as the SpiderMonkey and Rhino implementations, where functions have a special attribute __parent__ that can be referenced directly to the active object or global variable object that the function has created.
For example (SpiderMonkey, Rhino):
 code as follows:

var global = this;
var a = 10;
function foo () {}
alert (foo.__parent__); Global
var VO = foo.__parent__;
alert (VO.A); 10
Alert (VO = = global); True

As we can see in the above example, the function foo is created in the global context, so the attribute __parent__ to the variable object in the global context, the global object.
However, it is not possible to access the active object in the same way in SpiderMonkey: in different versions of the SpiderMonkey, the __parent__ of the internal function sometimes points to null and sometimes points to the global object.
In rhino, it is perfectly possible to access the active object in the same way.
For example (Rhino):
 code as follows:

var global = this;
var x = 10;
(function foo () {
var y = 20;
The active object in the "foo" context
var AO = (function () {}). __parent__;
Print (AO.Y); 20
The __parent__ of the currently active object is a global object that already exists
The special chain of the variable object forms a
So we call it the scope chain.
Print (ao.__parent__ = = global); True
Print (ao.__parent__.x); 10
})();

Summarize
In this article, we delve into the objects that are related to the execution context. I hope that this knowledge will help you to solve some of the problems you have encountered or confusion. According to the plan, in the following chapters, we will explore the scope chain, identifier resolution, closure.
If you have any questions, I'm glad to be able to answer them in the comments below.
Other reference
    • 10.1.3–variable instantiation;
    • 10.1.5–global Object;
    • 10.1.6–activation Object;
    • 10.1.8–arguments Object.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.