search
HomeWeb Front-endJS TutorialIn-depth understanding of JavaScript series (12) Variable Object (Variable Object)_javascript skills

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'] =
// 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
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
From Websites to Apps: The Diverse Applications of JavaScriptFrom Websites to Apps: The Diverse Applications of JavaScriptApr 22, 2025 am 12:02 AM

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python vs. JavaScript: Use Cases and Applications ComparedPython vs. JavaScript: Use Cases and Applications ComparedApr 21, 2025 am 12:01 AM

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

The Role of C/C   in JavaScript Interpreters and CompilersThe Role of C/C in JavaScript Interpreters and CompilersApr 20, 2025 am 12:01 AM

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript in Action: Real-World Examples and ProjectsJavaScript in Action: Real-World Examples and ProjectsApr 19, 2025 am 12:13 AM

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

JavaScript and the Web: Core Functionality and Use CasesJavaScript and the Web: Core Functionality and Use CasesApr 18, 2025 am 12:19 AM

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding the JavaScript Engine: Implementation DetailsUnderstanding the JavaScript Engine: Implementation DetailsApr 17, 2025 am 12:05 AM

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python vs. JavaScript: The Learning Curve and Ease of UsePython vs. JavaScript: The Learning Curve and Ease of UseApr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python vs. JavaScript: Community, Libraries, and ResourcesPython vs. JavaScript: Community, Libraries, and ResourcesApr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

See all articles

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

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software