JavaScript running mechanism sample code analysis
Start with a simple question:
<script type="text/javascript"> alert(i); var i = 1; </script>
Output results is undefined. This phenomenon is called "pre-parsing": the JavaScript engine will parse var variables and function definitions first. The code is not executed until pre-parsing is complete. If a document stream contains multiple script code segments (js code separated by script tags or imported js files).
The running sequence is:
step1. Read the first code Section
step2. Do syntax analysis. If there are errors, a syntax error will be reported (such as mismatched brackets, etc.), and jump to step5
step3. Do "pre-parsing" of var variables and function definitions (no errors will ever be reported) , because only correct declarations are parsed)
step4. Execute the code segment, and report an error if there is an error (for example, the variable is undefined)
step5. If there is another code segment, read the next code segment, and repeat step2
step6. End
The above analysis has been able to explain many problems, but I always feel that there is something missing. For example, in step 3, what exactly is "pre-parsing"? And in step 4, look at the following example:
<script type="text/javascript"> alert(i); // error: i is not defined. i = 1; </script>
Why does the first sentence cause an error? In JavaScript, don’t variables need to be undefined?
Compilation process
Time flies by like a white horse. Next to the bookcase, I open the "Principles of Compilation" that seems to be from another world. There is such a note in the familiar yet unfamiliar blank space:
For traditional compiled languages, the compilation steps are divided into: lexical analysis, syntax analysis, semantic checking, code optimization and byte generation.
But for interpreted languages, after the syntax tree is obtained through lexical analysis and syntax analysis, interpretation and execution can begin.
Simply put, lexical analysis is to convert a character stream (char stream) into a token stream (token stream), such as converting c = a – b; to:
NAME "c" EQUALS NAME "a" MINUS NAME "b" SEMICOLON
The above is just an example , for further understanding, please check out Lexical Analysis.
Chapter 2 of "The Definitive Guide to JavaScript", which talks about lexical structure (Lexical Structure), which is also described in ECMA-262. Lexical structure is the basis of a language and is easy to master. As for the implementation of lexical analysis, that is another research area and will not be explored here.
We can use the analogy of natural language. Lexical analysis is a one-to-one hard translation. For example, if a paragraph of English is translated into Chinese word by word, what we get is a bunch of token streams, which is difficult to understand. Further translation requires grammatical analysis. The following figure is a syntax tree of a conditional statement:
When constructing the syntax tree, if it is found that it cannot be constructed, such as if(a { i = 2; }, it will Report a syntax error and end the parsing of the entire code block. This is step 2 at the beginning of this article.
After constructing a syntax tree through syntax analysis, the translated sentences may still be ambiguous. Next, further semantic checking is required. For traditional strongly typed languages, the main part of semantic checking is type checking, such as whether the actual parameter and formal parameter types of the function match. For weakly typed languages, this step may not be available ( I have limited energy and do not have time to look at the JS engine implementation. I am not sure whether there is a semantic check step in the JS engine)
It can be seen from the above analysis that for the JavaScript engine, there must be lexical analysis. and syntax analysis, followed by semantic checking, code optimization and other steps. After these compilation steps are completed (any language has a compilation process, but interpreted languages are not compiled into binary code), the code will start to be executed
.The above compilation process still cannot explain the "pre-parsing" at the beginning of the article in more depth. We have to carefully explore the execution process of the JavaScript code
weeks. Aimin has a very careful analysis of this in the second part of "The Essence of JavaScript Language and Programming Practice". Here are some of my insights:
Through compilation, the JavaScript code has been translated into a syntax tree, and then it will be. Immediately execute according to the syntax tree.
For further execution, you need to understand the scope mechanism of JavaScript. JavaScript uses lexical scope. In layman's terms, the scope of JavaScript variables is defined. It is determined at the time of execution rather than at execution time, which means that the lexical scope depends on the source code and can be determined by the compiler through static analysis. Therefore, the lexical scope is also called static scope (static scope). However, you need to pay attention to the semantics of with and eval. It cannot be achieved only through static technology. In fact, it can only be said that the scope mechanism of JS is very close to lexical scope.
The JS engine creates an execution context when executing each function instance. The context contains a call object. The call object is a scriptObject structure, which is used to save the internal variable table varDecls, the embedded function table funDecls, the parent reference list upvalue and other syntax analysis structures (note: varDecls and funDecls and other information are It has been obtained during the syntax analysis stage and saved in the syntax tree. When the function instance is executed, this information will be copied from the syntax tree to the scriptObject). scriptObject is a set of static systems related to functions, consistent with the life cycle of function instances.
lexical scope是JS的作用域机制,还需要理解它的实现方法,这就是作用域链(scope chain)。scope chain是一个name lookup机制,首先在当前执行环境的scriptObject中寻找,没找到,则顺着upvalue到父级scriptObject中寻找,一直 lookup到全局调用对象(global object)。
当一个函数实例执行时,会创建或关联到一个闭包(closure)。 scriptObject用来静态保存与函数相关的变量表,closure则在执行期动态保存这些变量表及其运行值。closure的生命周期有可能比函数实例长。函数实例在活动引用为空后会自动销毁,closure则要等要数据引用为空后,由JS引擎回收(有些情况下不会自动回收,就导致了内存泄漏)。
别被上面的一堆名词吓住,一旦理解了执行环境、调用对象、闭包、词法作用域、作用域链这些概念,JS语言的很多现象都能迎刃而解。
小结
至此,对于文章开头部分的疑问,可以解释得很清楚了:
step3中所谓的“预解析”,其实是在step2的语法分析阶段完成,并存储在语法树中。当执行到函数实例时,会将varDelcs和funcDecls从语法树中复制到执行环境的scriptObject上。
step4中,未定义变量意味着在scriptObject的变量表中找不到,JS引擎会沿着scriptObject的upvalue往上寻找,如果都没找到,对于写操作i = 1; 最后就会等价为 window.i = 1; 给window对象新增了一个属性。对于读操作,如果一直追溯到全局执行环境的scriptObject上都找不到,就会产生运行期错误。
理解后,雾散花开,天空一片晴朗。
最后,留个问题给大家:
<script type="text/javascript"> var arg = 1; function foo(arg) { alert(arg); var arg = 2; } foo(3); </script>
请问alert的输出是什么?
The above is the detailed content of JavaScript running mechanism sample code analysis. For more information, please follow other related articles on the PHP Chinese website!

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 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.

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'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.

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 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 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 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.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

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

Hot Article

Hot Tools

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
Useful JavaScript development tools

Atom editor mac version download
The most popular open source editor

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

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