Table of Contents
1. Global initialization
2. Execution function A
3. Execute function B
简单的总结语
Home Web Front-end JS Tutorial Detailed introduction to JavaScript from definition to execution, what all programmers should know

Detailed introduction to JavaScript from definition to execution, what all programmers should know

Mar 10, 2017 pm 02:43 PM

From definition to execution of JavaScript, the JS engine does a lot of initialization work at the implementation layer. Therefore, before learning the working mechanism of the JS engine, we need to introduce several related concepts: execution environment stack, global object , execution environment, variable objects, active objects, scopes and scope chains, etc. These concepts are the core components of the JS engine. The purpose of this article is not to explain each concept to you in isolation, but to use a simple demo to conduct analysis and comprehensively explain every detail of the JS engine from definition to execution, as well as the role these concepts play in it.

var x = 1;  //定义一个全局变量 x
function A(y){
   var x = 2;  //定义一个局部变量 x
   function B(z){ //定义一个内部函数 B
       console.log(x+y+z);
   }
   return B; //返回函数B的引用
}
var C = A(1); //执行A,返回B
C(1); //执行函数B
Copy after login

This demo is a closure, the execution result is 4, we will divide it below Global initialization, Execute function A, Execute function B Three stages to analyze the working mechanism of the JS engine:

1. Global initialization

When the JS engine enters a piece of executable code, it needs to complete the following three initialization tasks:

First, create a global object (Global Object). There is only one copy of this object globally. A property is accessible from anywhere and exists throughout the application's lifetime. When the global object is created, commonly used JS objects such as Math, String, Date, and document are used as its attributes. Since this global object cannot be accessed directly by name, there is another attribute window, and window is pointed to itself, so that the global object can be accessed through window. The general structure of the global object simulated with pseudo code is as follows:

//创建一个全局对象
var globalObject = { 
    Math:{},
    String:{},
    Date:{},
    document:{}, //DOM操作
    ...
    window:this //让window属性指向了自身
}
Copy after login

Then, the JS engine needs to build an execution environment stack (Execution Context Stack). At the same time, Also create a global execution environment (Execution Context) EC and push this global execution environment EC into the execution environment stack. The function of the execution environment stack is to ensure that the program can be executed in the correct order. In JavaScript, each function has its own execution environment. When a function is executed, the execution environment of the function will be pushed to the top of the execution environment stack and obtain execution rights. When the function completes execution, its execution environment is removed from the top of the stack and the execution rights are returned to the previous execution environment. We use pseudo code to simulate the relationship between the execution environment stack and EC:

var ECStack = []; //定义一个执行环境栈,类似于数组

var EC = {};   //创建一个执行空间,
//ECMA-262规范并没有对EC的数据结构做明确的定义,你可以理解为在内存中分配的一块空间

ECStack.push(EC); //进入函数,压入执行环境
ECStack.pop(EC);  //函数返回后,删除执行环境
Copy after login

Finally, the JS engine also creates a global variable object (Varibale) associated with EC Object) VO, and point VO to the global object. VO not only contains the original properties of the global object, but also includes the globally defined variable x and function A. At the same time, when defining function A, it also adds Create an internal attribute scope and point the scope to VO. When each function is defined, a scope attribute is created associated with it. The scope always points to the environment in which the function is defined. The ECStack structure at this time is as follows:

ECStack = [   //执行环境栈
    EC(G) = {   //全局执行环境
        VO(G):{ //定义全局变量对象
            ... //包含全局对象原有的属性
            x = 1; //定义变量x
            A = function(){...}; //定义函数A
            A[[scope]] = this; //定义A的scope,并赋值为VO本身
        }
    }
];
Copy after login

2. Execution function A

When execution enters A(1), the JS engine needs to complete the following Work:

First, the JS engine will create the execution environment EC of function A, and then the EC is pushed to the top of the execution environment stack and obtains execution rights. At this time, there are two execution environments in the execution environment stack, namely the global execution environment and the execution environment of function A. The execution environment of A is at the top of the stack, and the global execution environment is at the bottom of the stack. Then, create the scope chain (Scope Chain) of function A. In JavaScript, each execution environment has its own scope chain for identifier resolution. When the execution environment is created, its scope chain is initialized. It is the object contained in the scope of the currently running function.

Then, the JS engine will create an Activation Object (Activation Object) AO of the current function. The activity object here plays the role of a variable object, but its name is different in the function (you can think of the variable object is a general concept, and the active object is a branch of it), AO contains the formal parameters of the function, the arguments object, this object, and the definition of local variables and internal functions, and then the AO will be pushed into the scope chain top. It should be noted that when defining function B, the JS engine will also add a scope attribute to B and point the scope to the environment where function B is defined. The environment where function B is defined is the active object AO of A. AO is located at the front end of the linked list. Since the linked list is connected end to end, the scope of function B points to the entire scope chain of A. Let’s take a look at the ECStack structure at this time:

ECStack = [   //执行环境栈
    EC(A) = {   //A的执行环境
        [scope]:VO(G), //VO是全局变量对象
        AO(A) : { //创建函数A的活动对象
            y:1,
            x:2,  //定义局部变量x
            B:function(){...}, //定义函数B
            B[[scope]] = this; //this指代AO本身,而AO位于scopeChain的顶端,因此B[[scope]]指向整个作用域链
            arguments:[],//平时我们在函数中访问的arguments就是AO中的arguments
            this:window  //函数中的this指向调用者window对象
        },
        scopeChain:<AO(A),A[[scope]]>  //链表初始化为A[[scope]],然后再把AO加入该作用域链的顶端,此时A的作用域链:AO(A)->VO(G)
    },
    EC(G) = {   //全局执行环境
        VO(G):{ //创建全局变量对象
            ... //包含全局对象原有的属性
            x = 1; //定义变量x
            A = function(){...}; //定义函数A
            A[[scope]] = this; //定义A的scope,A[[scope]] == VO(G)
        }
    }
];
Copy after login

3. Execute function B

After function A is executed, a reference to B is returned , and assigned to variable C. Executing C(1) is equivalent to executing B(1). The JS engine needs to complete the following work:

首先,还和上面一样,创建函数B的执行环境EC,然后EC推入执行环境栈的顶部并获取执行权。 此时执行环境栈中有两个执行环境,分别是全局执行环境和函数B的执行环境,B的执行环境在栈顶,全局执行环境在栈的底部。(注意:当函数A返回后,A的执行环境就会从栈中被删除,只留下全局执行环境)然后,创建函数B的作用域链,并初始化为函数B的scope所包含的对象,即包含了A的作用域链。最后,创建函数B的活动对象AO,并将B的形参z, arguments对象 和 this对象作为AO的属性。此时ECStack将会变成这样:

ECStack = [   //执行环境栈
    EC(B) = {   //创建B的执行环境,并处于作用域链的顶端
        [scope]:AO(A), //指向函数A的作用域链,AO(A)->VO(G)
        var AO(B) = { //创建函数B的活动对象
            z:1,
            arguments:[],
            this:window
        }
        scopeChain:<AO(B),B[[scope]]>  //链表初始化为B[[scope]],再将AO(B)加入链表表头,此时B的作用域链:AO(B)->AO(A)-VO(G)
    },
    EC(A), //A的执行环境已经从栈顶被删除,
    EC(G) = {   //全局执行环境
        VO:{ //定义全局变量对象
            ... //包含全局对象原有的属性
            x = 1; //定义变量x
            A = function(){...}; //定义函数A
            A[[scope]] = this; //定义A的scope,A[[scope]] == VO(G)
        }
    }
];
Copy after login

当函数B执行“x+y+z”时,需要对x、y、z 三个标识符进行一一解析,解析过程遵守变量查找规则:先查找自己的活动对象中是否存在该属性,如果存在,则停止查找并返回;如果不存在,继续沿着其作用域链从顶端依次查找,直到找到为止,如果整个作用域链上都未找到该变量,则返回“undefined”。从上面的分析可以看出函数B的作用域链是这样的:

AO(B)->AO(A)->VO(G)
Copy after login

因此,变量x会在AO(A)中被找到,而不会查找VO(G)中的x,变量y也会在AO(A)中被找到,变量z 在自身的AO(B)中就找到了。所以执行结果:2+1+1=4.

简单的总结语

了解了JS引擎的工作机制之后,我们不能只停留在理解概念的层面,而要将其作为基础工具,用以优化和改善我们在实际工作中的代码,提高执行效率,产生实际价值才是我们的真正目的。就拿变量查找机制来说,如果你的代码嵌套很深,每引用一次全局变量,JS引擎就要查找整个作用域链,比如处于作用域链的最底端window和document对象就存在这个问题,因此我们围绕这个问题可以做很多性能优化的工作,当然还有其他方面的优化,此处不再赘述,本文仅当作抛砖引玉吧!

The above is the detailed content of Detailed introduction to JavaScript from definition to execution, what all programmers should know. For more information, please follow other related articles on the PHP Chinese website!

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)

How to implement an online speech recognition system using WebSocket and JavaScript How to implement an online speech recognition system using WebSocket and JavaScript Dec 17, 2023 pm 02:54 PM

How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

WebSocket and JavaScript: key technologies for implementing real-time monitoring systems WebSocket and JavaScript: key technologies for implementing real-time monitoring systems Dec 17, 2023 pm 05:30 PM

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

The definition and function of MySQL composite primary key The definition and function of MySQL composite primary key Mar 15, 2024 pm 05:18 PM

The composite primary key in MySQL refers to the primary key composed of multiple fields in the table, which is used to uniquely identify each record. Unlike a single primary key, a composite primary key is formed by combining the values ​​of multiple fields. When creating a table, you can define a composite primary key by specifying multiple fields as primary keys. In order to demonstrate the definition and function of composite primary keys, we first create a table named users, which contains three fields: id, username and email, where id is an auto-incrementing primary key and user

What is Discuz? Definition and function introduction of Discuz What is Discuz? Definition and function introduction of Discuz Mar 03, 2024 am 10:33 AM

"Exploring Discuz: Definition, Functions and Code Examples" With the rapid development of the Internet, community forums have become an important platform for people to obtain information and exchange opinions. Among the many community forum systems, Discuz, as a well-known open source forum software in China, is favored by the majority of website developers and administrators. So, what is Discuz? What functions does it have, and how can it help our website? This article will introduce Discuz in detail and attach specific code examples to help readers learn more about it.

JavaScript and WebSocket: Building an efficient real-time weather forecasting system JavaScript and WebSocket: Building an efficient real-time weather forecasting system Dec 17, 2023 pm 05:13 PM

JavaScript and WebSocket: Building an efficient real-time weather forecast system Introduction: Today, the accuracy of weather forecasts is of great significance to daily life and decision-making. As technology develops, we can provide more accurate and reliable weather forecasts by obtaining weather data in real time. In this article, we will learn how to use JavaScript and WebSocket technology to build an efficient real-time weather forecast system. This article will demonstrate the implementation process through specific code examples. We

Simple JavaScript Tutorial: How to Get HTTP Status Code Simple JavaScript Tutorial: How to Get HTTP Status Code Jan 05, 2024 pm 06:08 PM

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

Introduction to PHP interfaces and how to define them Introduction to PHP interfaces and how to define them Mar 23, 2024 am 09:00 AM

Introduction to PHP interface and how it is defined. PHP is an open source scripting language widely used in Web development. It is flexible, simple, and powerful. In PHP, an interface is a tool that defines common methods between multiple classes, achieving polymorphism and making code more flexible and reusable. This article will introduce the concept of PHP interfaces and how to define them, and provide specific code examples to demonstrate their usage. 1. PHP interface concept Interface plays an important role in object-oriented programming, defining the class application

The definition and use of full-width characters The definition and use of full-width characters Mar 25, 2024 pm 03:33 PM

What are full-width characters? In computer encoding systems, double-width characters are a character encoding method that takes up two standard character positions. Correspondingly, the character encoding method that occupies a standard character position is called a half-width character. Full-width characters are usually used for input, display and printing of Chinese, Japanese, Korean and other Asian characters. In Chinese input methods and text editing, the usage scenarios of full-width characters and half-width characters are different. Use of full-width characters Chinese input method: In the Chinese input method, full-width characters are usually used to input Chinese characters, such as Chinese characters, symbols, etc.

See all articles