[JavaScript] ECMA-262-3 in-depth analysis. Chapter 2. variable objects

Source: Internet
Author: User
Introduction
Data Declaration
Variable objects in different execution contexts
Variable objects in the Global Context
Variable objects in the function last afternoon
Process contextual code in stages
Enter execution Context
Execute Code
About Variables
Special implementation: _ parent _ attribute
Conclusion
Other references

When creating an application, we can never declare variables or functions. So when we need to use these things, how does the interpreter (interpreter) find our data (functions, variables)? What exactly does this process happen?

Most ECMAScript programmers should know that variables are closely related to execution context:

var a = 10; // variable of the global context (function () {  var b = 20; // local variable of the function context})(); alert(a); // 10alert(b); // "b" is not defined

Similarly, many programmers know that, based on the specifications of the current version, the independent scope can only be created through the execution context of the "function" code type. For example, in ECMAScript,ForA loop cannot create a local context. (Translator's note: local scope ):

for (var k in {a: 1, b: 2}) {  alert(k);} alert(k); // variable "k" still in scope even the loop is finished

Let's take a look at the internal details when we declare the data.

Data Declaration

If the variable is related to the execution context, it should know where its data is stored and how to access it. This mechanism is calledVariable object).

Variable object (VO)It is the object related to the execution context (the Translator's note: This "object" refers to something), which stores the following content:

  • Variable (var, VariableDeclaration );
  • Function declaration (FunctionDeclaration );
  • And function parameters

The preceding statements are declared in the context.

A simple example is as follows. A variable object may be expressed in the form of a normal ECMAScript object:

VO = {};

As we mentioned earlier, VO is the property of the execution context ):

activeExecutionContext = {  VO: {    // context data (var, FD, function arguments)  }};

OnlyGlobal ContextThe variable object can be indirectly accessed through the VO attribute name (because in the global context, the global object itself is a variable object, which will be detailed later ). In other contexts, it is impossible to directly access VO, because the variable object is completely internal to the implementation mechanism.

When we declare a variable or a function, we also use the variable name and value to create a new attribute in VO.

For example:

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

The corresponding variable object is:

// Variable object of the global contextVO(globalContext) = {  a: 10,  test: };// Variable object of the "test" function contextVO(test functionContext) = {  x: 30,  b: 20};

At the specific implementation level (and in the standard), variable objects are just abstract things. (Translator's note: This sentence is not very smooth. You are welcome to provide a better translation .) Essentially, the name and initial structure of VO are different in different execution contexts.

Variable objects in different execution contexts

For all types of execution contexts, some operations (such as variable initialization) and actions of the variable object are common. From this perspective, it is easier to understand the variable object as an abstract basic thing. In the context of a function, you can define additional details through variable objects.

Next, we will discuss in detail;

Variable objects in the Global Context

It is necessary to firstGlobal object)A clear definition:

Global object)Is an object that has been created before entering any execution context; this object only exists, and its attributes can be accessed anywhere in the program, the life cycle of the global object ends when the program exits.

In the initial creation phase, the global object is initialized through attributes such as Math, String, Date, and parseInt. Other objects can also be appended as attributes, including objects that can reference the global object itself. For example, in DOM, the window attribute of the global object is to reference the attributes of the Global Object (Of course, not all implementations are like this ):

global = {  Math: <...>,  String: <...>  ...  ...  window: global};

Because global objects cannot be accessed directly by name, the prefix is usually ignored when accessing global object attributes. However, this in the global context can still directly access the global object, and can also be accessed by referencing its own attributes. For exampleWindow. To sum up, the code can be abbreviated:

String(10); // means global.String(10);// with prefixeswindow.a = 10; // === global.window.a = 10 === global.a = 10;this.b = 20; // global.b = 20;

Therefore, the variable object in the global context isGlobal object itself):

VO(globalContext) === global;

Accurately understand that "the variable object in the global context isGlobal object itself"Is very necessary. Based on this fact, when a variable is declared in the global context, we can indirectly access this variable through the attributes of the Global Object (for example, when the variable name is unknown in advance ):

var a = new String('test');alert(a); // directly, is found in VO(globalContext): "test"alert(window['a']); // indirectly via global === VO(globalContext): "test"alert(a === this.a); // truevar aKey = 'a';alert(window[aKey]); // indirectly, with dynamic property name: "test" 
Variable objects in the function Context

In the context of function execution, VO cannot be accessed directly.Activation object (AO)Play the role of VO.

VO(functionContext) === AO;

Activation objectIs created when the context of the function is entered.ArgumentsAttribute initialization. The value of the grguments attribute isArguments object:

AO = {  arguments: <ArgO>};

Arguments objectsIs an internal object in the activation object in the function context. It includes the following attributes:

  • Callee-Point to the reference of the current function;
  • Length-True TransferThe number of parameters;
  • Properties-indexes(An integer of the string type) the attribute value is the parameter value of the function (arranged from left to right by the parameter list ). The number of internal elements in properties-indexes is equalArguments. length. Properties-the value of indexes isShared. (Note: The difference between sharing and non-sharing can be compared and understood as the difference between reference transfer and value transfer)

For example:

function foo(x, y, z) {  alert(arguments.length); // 2 – quantity of passed arguments  alert(arguments.callee === foo); // true  alert(x === arguments[0]); // true  alert(x); // 10  arguments[0] = 20;  alert(x); // 20  x = 30;  alert(arguments[0]); // 30  // however, for not passed argument z,  // related index-property of the arguments  // object is not shared  z = 40;  alert(arguments[2]); // undefined  arguments[2] = 50;  alert(z); // 40}foo(10, 20); 

In the last example, There is a bug in the current Google Chrome browser-even if the parameter z is not passed,ZAndArguments [2]Still shared. (Translator's note: I tested this bug in Chrome Ver4.1.249.1059)

Process contextual code in stages

Now we have finally reached the core content of this article. The execution context code is divided into two basic stages for processing:

  • Enter the execution context;
  • Run the code;

Changes in variable objects are closely related to these two phases.

Enter execution Context

When you enter the execution context (before code execution), VO is filled with the following attributes (all of which have been described previously ):

  • All functionsFormat parameters(If we are in the context of function execution)
  • -An attribute of a variable object, which consists of the name and value of a formal parameter. If no actual parameter is passed, this attribute is composed of the name of the formal parameter and the undefined value;

  • AllFunction declaration (FunctionDeclaration, FD)
  • -A property of a variable object, which consists of the name and value of a function object. If the variable object already has an attribute with the same name, it is completely replaced.

  • AllVariable Declaration (var, VariableDeclaration)
  • -An attribute of a variable object, which consists of the variable name and undefined value. If the variable name is the same as the declared formal parameter or function, the variable declaration does not interfere with the existing attributes.

Let's take an example:

function test(a, b) {  var c = 10;  function d() {}  var e = function _e() {};  (function x() {});}test(10); // call 

WhenEnterWhen the context of the "test" function (passing the parameter 10), AO is as follows:

AO(test) = {  a: 10,  b: undefined,  c: undefined,  d: <reference to FunctionDeclaration "d">  e: undefined};

Note: The AO does not contain functions."X". This is because"X"IsFunction expression (FunctionExpression, abbreviated as FE)Instead of function declaration, function expressionsNo effectVO (Note: VO here refers to AO ). Function"_ E"It is also a function expression, but as we will see below, because it is assigned to the variable "e", it becomes accessible through the name "e.FunctionDeclarationAndFunctionExpressionThe difference will be discussed in detail in Chapter 5. Functions.

After that, the second stage of processing the context code is executed.

Execute Code

At this moment, AO/VO has been attribute (however, not all attributes have values, and most of the attribute values are the default values of the system.Undefined.

In the previous example, AO/VO was modified as follows during code interpretation:

AO['c'] = 10;AO['e'] = <reference to FunctionExpression "_e">;

Pay attention again becauseFunctionExpression"_ E" is saved to the declared variable "e", so it still exists in the memory (Note: it is still in AO/VO ). WhileFunctionExpression. An unsaved function expression can be called only in its own definition or recursion. "X" does not exist in AO/VO. That is, if we want to call the "x" function, an error will occur no matter before or after the function is defined."X is not defined"

Another typical example:

alert(x); // functionvar x = 10;alert(x); // 10x = 20;function x() {};alert(x); // 20 

Why does the first alert "x" return a function, and it still accesses "x" before "x" is declared? Why not 10 or 20? Because, according to the specification-when entering the context, fill in the function declaration in VO; at the same stage, there is also a variable Declaration "x", as we said in the previous stage, variable declarations follow the declaration of functions and formal parameters in sequence, and at this stage (Note: This stage refers to entering the execution context stage ), variable declaration does not interfere with the declaration of functions with the same name or form parameters in VO. Therefore, when entering the context, the VO structure is as follows:

VO = {}; VO['x'] = <reference to FunctionDeclaration "x"> // found var x = 10;// if function "x" would not be already defined// then "x" be undefined, but in our case// variable declaration does not disturb// the value of the function with the same name VO['x'] = <the value is not disturbed, still function>

Then, in the code execution stage, VO makes the following changes:

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

We can see this effect in the second and third alert.

In the following example, we can see that the variables are put into VO at the context stage. (Because, although some else code will never be executed, the variable "B" still exists in VO .) (Note: although variable B exists in VO, the value of variable B is always undefined)

if (true) {  var a = 1;} else {  var b = 2;}alert(a); // 1alert(b); // undefined, but not "b is not defined" 
About Variables

Generally, various articles and JavaScript-related books claim that "a variable can be declared whether the var keyword is used (in the Global Context) or the var keyword is not used (anywhere ". Remember, this is a rumor:

Variables can only be declared by using the var keyword at any time.

Then assign as follows:

 a = 10; 

This only creates a new attribute for the Global Object (but it is not a variable ). "Not a variable" does not mean that it cannot be changed, but does not comply with the variable concept in the ECMAScript specification, so it is "not a variable" (the reason why it can become a global object attribute, this is because VO (globalContext) = global. Do you still remember this ?).

Let's take a look at the specific differences through the following examples:

alert(a); // undefinedalert(b); // "b" is not definedb = 10;var a = 20; 

The root cause is still VO and its modification phase (Enter ContextPHASE ANDExecute CodePhase ):

Enter the context stage:

VO = {  a: undefined}; 

We can see that "B" is not a variable, so there is no "B" at this stage ", "B" will only appear in the code execution phase (but in our example, an error has occurred before it reaches ).

Let's change the example code:

alert(a); // undefined, we know whyb = 10;alert(b); // 10, created at code executionvar a = 20;alert(a); // 20, modified at code execution 

There is also an important knowledge point about variables. Compared with simple attributes, a variable has an attribute ):{DontDelete}The meaning of this feature is differentDeleteThe operator directly deletes the variable property.

a = 10;alert(window.a); // 10alert(delete a); // truealert(window.a); // undefinedvar b = 20;alert(window.b); // 20alert(delete b); // falsealert(window.b); // still 20 

HoweverEvalContext, this rule does not work, because in this context, the variable does not have the {DontDelete} feature.

eval('var a = 10;');alert(window.a); // 10alert(delete a); // truealert(window.a); // undefined

When you use a debugging tool (for example, Firebug) to test the instance, you must note that Firebug also uses eval to execute your code on the console. Therefore, the variable property does not exist.{DontDelete}Feature, which can be deleted.

Special implementation: _ parent _ attribute

As mentioned above, activation objects cannot be directly accessed according to standard specifications. However, some specific implementations do not fully comply with this provision, such as SpiderMonkey and Rhino. In these specific implementations, the function has a special attribute._ Parent __You can use this attribute to directly reference the activated object or global variable object created by the function.

For example (SpiderMonkey, Rhino ):

var global = this;var a = 10;function foo() {}alert(foo.__parent__); // globalvar VO = foo.__parent__;alert(VO.a); // 10alert(VO === global); // true 

In the above example, we can see that the functionFooIs created in the global context, so the attribute_ Parent __The variable object pointing to the global context, that is, the global object. (Note: Remember this: VO (globalContext) = global)

However, it is impossible to access the activated object in the same way in SpiderMonkey: in different versions of SpiderMonkey, the internal function_ Parent __Sometimes pointNull, Sometimes pointing to a global object.

In Rhino, you can access the activated object in the same way.

For example (Rhino ):

var global = this;var x = 10;(function foo() {  var y = 20;  // the activation object of the "foo" context  var AO = (function () {}).__parent__;  print(AO.y); // 20  // __parent__ of the current activation  // object is already the global object,  // i.e. the special chain of variable objects is formed,  // so-called, a scope chain  print(AO.__parent__ === global); // true  print(AO.__parent__.x); // 10})(); 
Conclusion

In this article, we further studied objects related to execution context. I hope this knowledge can help you solve some problems or confusions you have encountered. As planned, we will discuss in subsequent chaptersScope chain,Identifier resolution,Closures.

If you have any questions, I am happy to answer them in the following comments.

Other references
  • 10.1.3-Variable Instantiation;
  • 10.1.5-Global Object;
  • 10.1.6-Activation Object;
  • 10.1.8-Arguments Object.

 

English address:ECMA-262-3 in detail. Chapter 2. Variable object
Chinese address: [JavaScript] ECMA-262-3 in-depth analysis. Chapter 2. variable objects

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.