Home Web Front-end JS Tutorial In-depth understanding of JavaScript series (12) Variable Object (Variable Object)_javascript skills

In-depth understanding of JavaScript series (12) Variable Object (Variable Object)_javascript skills

May 16, 2016 pm 05:57 PM
object variable

When programming JavaScript, we cannot avoid declaring functions and variables in order to successfully build our system, but how and where does the interpreter find these functions and variables? What exactly happens when we reference these objects?
Original release: Dmitry A. Soshnikov
Published 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/
Partially difficult to translate The sentence refers to the Chinese translation of justinw
Most ECMAScript programmers should know that variables are closely related to execution context:

Copy code The code is as follows:

var a = 10; // Variables in the global context
(function () {
var b = 20; // Local variables in the function context
})();
alert(a); // 10
alert(b); // Global variable "b" is not declared

Also, many programmers As we all know, the current ECMAScript specification states that independent scopes can only be created through an execution context of the "function" code type. In other words, compared to C/C, the for loop in ECMAScript cannot create a local context.
Copy code The code is as follows:

for (var k in {a: 1, b: 2}) {
alert(k);
}
alert(k); // Although the loop has ended, the variable k is still in the current scope

Let’s see Take a look at what details we discovered when we declared the data.
Data declaration
If the variable is related to the execution context, the variable itself should know where its data is stored and know how to access it. This mechanism is called a variable object.
Variable object (abbreviated as VO) is a special object related to the execution context. It stores the following content declared in the context:
Variable (var, variable declaration);
FunctionDeclaration (FunctionDeclaration, Abbreviated as FD);
Formal parameters of function
For example, we can use ordinary ECMAScript objects to represent a variable object:
Copy code The code is as follows:

VO = {};
As we said, VO is the property of the execution context:
activeExecutionContext = {
VO: {
//Context data (var, FD, function arguments)
}
};

Only global context variable objects are allowed to pass VO Property name to access indirectly (because in the global context, the global object itself is a variable object, which will be introduced in detail later), the VO object cannot be directly accessed in other contexts, because it is only an implementation of the internal mechanism.
When we declare a variable or a function, there is no other difference from when we create a new attribute of VO (ie: there is a name and a corresponding value).
For example:
Copy code The code is as follows:

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

The corresponding variable object is:
Copy code The code is as follows:

// Global context variable object
VO(globalContext) = {
a: 10,
test:
};
// variable object of test function context
VO(test functionContext) = {
x: 30,
b: 20
};

At the specific implementation level (and in the specification) the variable object is just an abstract concept. (Essentially, in a specific execution context, the VO name is different, and the initial structure is also different.
Variable objects in different execution contexts
For all types of execution contexts, variable objects Some operations (such as variable initialization) and behaviors are common. From this perspective, it is easier to understand variable objects as abstract basic things and also define additional content related to variable objects in the context of functions.
Copy code The code is as follows:

Abstract variable object VO (general behavior of variable initialization process)

╠══> Global context variable object GlobalContextVO
║ (VO === this === global)

╚══> Function context variable object FunctionContextVO
(VO === AO, and added and )

Let’s take a closer look:
Variable objects in the global context
First, we need to give the global object a clear definition:
The global object (Global object) is created before entering any execution context. Object;
There is only one copy of this object, its properties can be accessed anywhere in the program, and the life cycle of the global object ends at the moment the program exits.
Copy code
In the initial creation phase of the global object, Math, String, Date, parseInt are used as its own attributes, and other attributes are initialized. It can also have other additional objects created as attributes (which can point to the global object itself). For example, in the DOM, the window attribute of the global object can refer to the global object itself (of course, not all specific implementations are like this):
Copy code The code is as follows:

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

The prefix is ​​usually ignored when accessing the properties of the global object, because the global Objects cannot be accessed directly by name. However, we can still access the global object through this of the global context, and we can also refer to itself recursively. For example, window in DOM. To sum up, the code can be abbreviated as:
Copy the code The code is as follows:

String( 10); // It is global.String(10);
// With prefix
window.a = 10; // === global.window.a = 10 === global.a = 10 ;
this.b = 20; // global.b = 20;

So, back to the variable object in the global context - in this case, the variable object is the global object itself:
VO(globalContext) === global;
It is very necessary to understand the above conclusion. Based on this principle, only when the correspondence is declared in the global context, we can access it indirectly through the properties of the global object (for example, in advance don't know the variable name).
Copy code The code is 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]); // indirectly through the dynamic property name Access: "test"

Variable object in function context
In the function execution context, VO cannot be accessed directly. At this time, it is played by the activation object (abbreviated as AO) The role of VO.
VO(functionContext) === AO;
The active object is created when entering the function context, and it is initialized through the arguments attribute of the function. The value of the arguments attribute is the Arguments object:
Copy code The code is as follows:

AO = {
arguments:
};

The Arguments object is an attribute of the active object, which includes the following attributes:
callee — a reference to the current function
length — The number of parameters actually passed
properties-indexes (integer of string type) The value of the property is the parameter value of the function (arranged from left to right in the parameter list). The number of elements inside properties-indexes is equal to arguments.length. The value of properties-indexes is shared with the parameters actually passed in.
For example:
Copy code The code is as follows:

function foo(x, y, z) {
// Number of declared function parameters arguments (x, y, z)
alert(foo.length); // 3
// The number of parameters 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, there is no parameter z and parameter passed in The 3rd index value is not shared
z = 40;
alert(arguments[2]); // undefined
arguments[2] = 50;
alert(z); / / 40
}
foo(10, 20);

The code for this example has a bug in the current version of Google Chrome — even if the parameters z, z are not passed and arguments[2] are still shared.
Two stages of processing context code
Now we have finally reached the core point of this article. The execution context code is divided into two basic stages for processing:
Entering the execution context
Executing code
Modifications of variable objects are closely related to these two stages.
Note: The processing in these two stages is a general behavior and has nothing to do with the type of context (that is, the performance is the same in global context and function context).
Enter the execution context
When entering the execution context (before code execution), VO already contains the following attributes (as mentioned earlier):
All formal parameters of the function (if we are in the function execution context Medium)
—A property of a variable object consisting of a name and a corresponding value is created; if no corresponding parameters are passed, a property of a variable object consisting of a name and an undefined value will also be created.
All function declarations (FunctionDeclaration, FD)
—A property of a variable object consisting of a name and a corresponding value (function-object) is created; if the variable object already has a property with the same name, it is completely Replace this attribute.
All variable declarations (var, VariableDeclaration)
—The properties of a variable object consisting of a name and a corresponding value (undefined) are created; if the variable name is the same as a declared formal parameter or function, the variable declaration will not Interfering with existing properties of this type.
Let’s look at an example:
Copy code The code is as follows:

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

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

AO(test) = {
a: 10,
b: undefined,
c : undefined,
d:
e: undefined
};

Note that AO does not contain function "x". This is because "x" is a function expression (FunctionExpression, abbreviated as FE) rather than a function declaration, and function expressions will not affect VO. Anyway, 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 function declaration FunctionDeclaration and function expression FunctionExpression will be discussed in detail in Chapter 15 Functions. You can also refer to Chapter 2 of this series to learn about named function expressions.
After this, you will enter the second stage of processing the context code - executing the code.
Code execution
During this cycle, AO/VO already has attributes (however, not all attributes have values, and the values ​​of most attributes are still the system default initial value of undefined).
Still with the previous example, AO/VO was modified as follows during code interpretation:
Copy the code The code is as follows:

AO['c'] = 10;
AO['e'] = ;

Note again, because FunctionExpression "_e" is saved to the declared variable "e", so it still exists in memory. FunctionExpression "x" does not exist in AO/VO, which means that if we try to call the "x" function, no matter before or after the function is defined, an error "x is not defined" will appear, and the function is not saved. An expression can only be called within its own definition or recursively.
Another classic example:
Copy code The code is 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 it accesses “x” before “x” is declared? Why not 10 or 20? Because, according to the specification, the function declaration is filled in when entering the context; agreeing with the cycle, there is also a variable declaration "x" when entering the context, then as we said in the previous stage, the variable declaration follows in sequence After the function declaration and formal parameter declaration, and during this context entry stage, the variable declaration will not interfere with the function declaration or formal parameter declaration of the same name that already exists in VO. Therefore, when entering the context, the structure of VO is as follows:
Copy code The code is as follows:

VO = {};
VO['x'] = < reference to FunctionDeclaration "x">
// Find var x = 10;
// If function "x" has not been declared
// At this time the value of "x" should be undefined
// But the variable declaration in this case does not affect the value of the function with the same name
VO['x'] =

Next, in During the code execution phase, VO makes the following modifications:
Copy the code The code is as follows:

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

We can see this effect in the second and third alerts.
In the example below we can see again that the variables are put into VO during the context phase. (Because, although the else part of the code will never be executed, the variable "b" still exists in VO anyway.)
Copy code The code is as follows:

if (true) {
var a = 1;
} else {
var b = 2;
}
alert (a); // 1
alert(b); // undefined, not that b is not declared, but that the value of b is undefined

About variables
Usually, various articles Books related to JavaScript all claim: "You can declare a variable whether using the var keyword (in the global context) or not using the var keyword (anywhere)." Remember, this is a misconception:
At any time, a variable can only be declared by using the var keyword.
The above assignment statement:
a = 10;
This just creates a new property for the global object (but it is not a variable). "Not a variable" does not mean that it cannot be changed, but that it does not conform to the variable concept in the ECMAScript specification, so it is "not a variable" (the reason why it can become a property of the global object is entirely because of VO(globalContext) = == global, do you still remember this? ).
Let’s take a look at the specific differences through the following examples:
Copy the code The code is as follows:

alert(a); // undefined
alert(b); // "b" is not declared
b = 10;
var a = 20;

All roots are still VO and enter context phase and code execution phase:
Enter context phase:
Copy code The code is as follows :

VO = {
a: undefined
};

We can see that because "b" is not a variable, at this stage There is no "b" at all, "b" will only appear during the code execution phase (but in our case, the error will occur before that).
Let’s change the example code:
Copy the code The code is as follows:

alert( a); // undefined, everyone knows this,
b = 10;
alert(b); // 10, created during the code execution phase
var a = 20;
alert(a) ; // 20, Modification during code execution phase

There is another important knowledge point about variables. Compared with simple attributes, variables have an attribute: {DontDelete}. The meaning of this attribute is that the variable attribute cannot be directly deleted using the delete operator.
Copy code The code is as follows:

a = 10;
alert(window.a); // 10
alert(delete a); // true
alert(window.a); >var b = 20;
alert(window.b); // 20
alert(delete b); // false
alert(window.b); // 여전히 20 >
그러나 이 규칙은 하나의 컨텍스트, 즉 eval 컨텍스트에서는 왜곡될 수 없으며 변수에는 {DontDelete} 속성이 없습니다.


코드 복사 코드는 다음과 같습니다. eval('var a = 10;' );
alert(window.a); // 10
alert(delete a); // true
alert(window.a) // 정의되지 않음


이 인스턴스를 테스트할 때 일부 디버깅 도구(예: Firebug) 콘솔을 사용하는 경우 Firebug도 eval을 사용하여 콘솔에서 코드를 실행한다는 점에 유의하세요. 따라서 변수 속성에도 {DontDelete} 속성이 없으므로 삭제가 가능합니다.
특수 구현: __parent__ 속성 ​​
앞서 언급했듯이 표준 사양에 따르면 활성 개체에 직접 액세스할 수 없습니다. 그러나 SpiderMonkey 및 Rhino와 같은 일부 특정 구현은 이 규정을 완전히 준수하지 않습니다. 구현 시 함수에는 특수 속성 __parent__이 있으며 이를 통해 함수가 생성한 활성 개체 또는 전역 변수 개체를 직접 참조할 수 있습니다.
예(SpiderMonkey, Rhino):



코드 복사 코드는 다음과 같습니다. var global = this;
var a = 10;
function foo() {}
alert(foo.__parent__); // global VO = foo.__parent__; Alert(VO.a); // 10
alert(VO === global); // true


위의 예에서 foo 함수가 전역에서 생성되는 것을 볼 수 있습니다. 따라서 __parent__ 속성은 전역 컨텍스트의 변수 객체, 즉 전역 객체를 가리킵니다.
그러나 SpiderMonkey에서는 동일한 방식으로 활성 개체에 액세스할 수 없습니다. 다른 버전의 SpiderMonkey에서는 내부 함수의 __parent__가 때때로 null을 가리키기도 하고 때로는 전역 개체를 가리키기도 합니다.
Rhino에서는 동일한 방식으로 활성 개체에 액세스하는 것이 완전히 가능합니다.
예(Rhino):




코드 복사
코드는 다음과 같습니다. var global = this ; var x = 10; (function foo() {
var y = 20;
// "foo" 컨텍스트의 활성 개체
var AO = (함수 () { }).__parent__;
print(AO.y); // 20
// 현재 활성 객체의 __parent__는 기존 전역 객체입니다.
// 변수 객체의 특수 체인
// 그래서 이를 범위 체인이라고 부릅니다.
print(AO.__parent__ === global); // true
print(AO.__parent__.x) // 10
})() ;


요약
이번 글에서는 실행 컨텍스트와 관련된 객체를 심층적으로 살펴보았습니다. 이 지식이 귀하에게 도움이 되기를 바라며 귀하가 직면한 몇 가지 문제나 혼란을 해결할 수 있기를 바랍니다. 계획대로 다음 장에서는 범위 체인, 식별자 확인 및 클로저를 살펴보겠습니다.
궁금한 점이 있으시면 아래 댓글로 답변해 드리겠습니다.
기타 참고자료


10.1.3 –
변수 인스턴스화
;
10.1.5 –
Statement of this Website
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

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What are the methods of converting java Object to byte and byte to Object? What are the methods of converting java Object to byte and byte to Object? Apr 20, 2023 am 11:37 AM

Object to byte and byte to Object Today we will realize how to convert from Object to byte and how to convert from byte to Object. First, define a class student: packagecom.byteToObject;importjava.io.Serializable;publicclassstudentimplementsSerializable{privateintsid;privateStringname;publicintgetSid(){returnsid;}publicvoidsetSid(in

PHP Notice: Undefined variable: solution in solution PHP Notice: Undefined variable: solution in solution Jun 22, 2023 pm 10:01 PM

For PHP developers, encountering the "Undefinedvariable" warning message is a very common thing. This situation usually occurs when trying to use undefined variables, which will cause the PHP script to fail to execute normally. This article will introduce how to solve the problem of "PHPNotice:Undefinedvariable: in solution". Cause of the problem: In a PHP script, if a variable is not initialized or assigned a value, "Un

How to use methods in Java Object class How to use methods in Java Object class Apr 18, 2023 pm 06:13 PM

1. Introduction to the Object class Object is a class provided by Java by default. Except for the Object class, all classes in Java have inheritance relationships. By default, it will inherit the Object parent class. That is, objects of all classes can be received using the reference of Object. Example: Use Object to receive objects of all classes classPerson{}classStudent{}publicclassTest{publicstaticvoidmain(String[]args){function(newPerson());function(newStudent());}public

Java uses the getClass() function of the Object class to obtain the runtime class of the object Java uses the getClass() function of the Object class to obtain the runtime class of the object Jul 24, 2023 am 11:37 AM

Java uses the getClass() function of the Object class to obtain the runtime class of the object. In Java, each object has a class, which defines the properties and methods of the object. We can use the getClass() function to get the runtime class of an object. The getClass() function is a member function of the Object class, so all Java objects can call this function. This article will introduce how to use the getClass() function and give some code examples. use get

What is the relationship between basic data types and Object in java What is the relationship between basic data types and Object in java May 01, 2023 pm 04:04 PM

The relationship between basic data types and Object. I know everyone has heard that Object is the base class of all types, but this sentence is actually not correct, because the basic data types in Java have nothing to do with Object. Here are some examples For example, when calling the swap method, you cannot directly pass the int type to the swap(Objectobj) method, because Object actually has nothing to do with the basic data type. At this time, a finds that our types do not match, so it automatically wraps it. It has become an Integer type. At this time, it can be contacted with Object and the swap method can be successfully called. Object, a wrapper class of basic data types

PHP Notice: Trying to get property of non-object solution PHP Notice: Trying to get property of non-object solution Jun 24, 2023 pm 09:34 PM

PHPNotice: Tryingtogetpropertyofnon-object Solution When you are developing in PHP, you may encounter this error message: "Notice: Tryingtogetpropertyofnon-object." This error message is usually due to you using an uninitialized object, or It's because your object has lost its reference in a certain piece of code and cannot access the properties correctly.

How to define the Object structure of redis How to define the Object structure of redis May 28, 2023 pm 05:20 PM

Introduction to the two-tier data structure of Redis. One of the reasons for the high performance of redis is that each of its data structures is specially designed and supported by one or more data structures. These flexible data structures are relied upon to improve reading performance. Fetch and write performance. If you want to understand the data structure of redis, you can discuss it from two different levels: The first level is from the user's perspective. This level is also the calling interface that Redis exposes to the outside, such as: string, list, hash ,set,sortedset. The second level is from the perspective of internal implementation, which belongs to the lower level implementation, such as: dict, sds, ziplist, quicklist, skiplis

How to use Object class and System class in Java? How to use Object class and System class in Java? Apr 23, 2023 pm 11:28 PM

Object is the base class of all Java classes, the top of the entire class inheritance structure, and the most abstract class. Everyone uses toString(), equals(), hashCode(), wait(), notify(), getClass() and other methods every day. Maybe they don’t realize that they are methods of Object, and they don’t look at what other methods Object has. And think about why these methods should be placed in Object. 1. Introduction to JavaObject class - the super class of all classes Object is a special class in the Java class library and is also the parent class of all classes. In other words, Java allows any type of object to be assigned to the Object type

See all articles