Javascript执行过程(二)

tech2025-09-04  54

了解javascript解析引擎

简单地说,JavaScript解析引擎就是能够“读懂”JavaScript代码,并准确地给出代码运行结果的一段程序。

比方说,当你写了 var a = 1 + 1; 这样一段代码,JavaScript引擎做的事情就是看懂(解析)你这段代码,并且将a的值变为2。

Javascript引擎的基本原理是: 它可以把JS的源代码转换成高效,优化的代码,这样就可以通过浏览器解析甚至可以被嵌入到应用当中。它的唯一目的是读取和编译javascript代码

JavaScript引擎是浏览器的组成部分之一,由于运行javascript代码环境的不同,所以对应的javascript引擎也不一样,常见的javascript引擎有如下:

Mozilla浏览器 -----> 解析引擎为 Spidermonkey(由c语言实现的) Chrome浏览器 ------> 解析引擎为 V8(它是由c++实现的) Safari浏览器 ------> 解析引擎为 JavaScriptCore(c/c++) IE and Edge ------> 解析引擎为 Chakra(c++) Node.js ------> 解析引擎为 V8

那么有不同的JavaScript引擎,就得有对应的解析规则,ECMAScript就定义了这些规则标准,JavaScript引擎就可以根据这个标准去解析JavaScript代码了

每个javascript引擎都实现了一个版本的ECMAScript,所以随着ECMAScript在不断的发展,javascript的引擎也会在不断的改变。

标准的JavaScript引擎就会根据ECMAScript这套文档去实现,注意这里强调了标准,因为也有不按照标准来实现的,比如IE的JS引擎。这也是为什么JavaScript会有兼容性的问题。

了解解析引擎是如何解析JS的

JavaScript引擎,不是逐条解释执行javaScript代码,而是按照代码块一段段解释执行。所谓代码块就是使用<script>标签分隔的代码段。

解析JS分为2个阶段:如下所示:

对于常见编译型语言(例如:Java)来说,编译步骤分为:词法分析->语法分析->语义检查->代码优化和字节生成。

对于解释型语言(例如JavaScript)来说,通过词法分析和语法分析得到语法树后,就可以开始解释执行了。

一、语法解析阶段

1.词法分析

词法分析是将字符流(char stream)转换为记号流(token stream),称之为 “词法单元”,就像英文句子一个个单词独立翻译,举例:

代码:var result = testNum1 - testNum2;

词法分析后 :

NAME “result”EQUALSNAME “testNum1”MINUSNAME “testNum2”SEMICOLON

2.语法分析

语法分析过程中会将词法单元流转换成一颗 抽象语法树(AST),举例:

条件语句 if(typeof a == “undefined” ){ a = 0; } else { a = a; } alert(a);

当JavaScript解释器在构造语法树的时候,如果发现无法构造,就会报语法错误,并结束整个代码块的解析。

二、运行阶段

1.预解析

在js文件或script里面的代码在正式开始执行之前,会进行一些解析工作,比如上在全局中寻找var关键字声明的变量和通过function关键字声明的函数。

找到全局变量或函数后,我们会对其进行作用域提升。

变量提升声明的情况下不会赋值操作,因此它的默认值是undefined函数提升声明,可以在声明函数体之前进行调用变量也可以在赋值之前进行输出,只是变量输出的值为undefined而已

比如如下代码(变量提升常见面试题):

var a = 1; function abc() { console.log(a); var a = 2; } abc();

如上代码,我们在全局变量中定义了一个变量a = 1; 在函数abc中先打印a,然后给 var a = 2; 进行赋值,但是最后打印的结果为undefined; 那是因为var在作用域中有提升的。上面的代码在预解析的时候,会被解析成如下代码:

var a = 1; function abc() { var a; console.log(a); a = 2; } abc();

预编译需要注意如下几个问题:

预编译首先是全局预编译,函数体未调用时是不进行预编译的。只有var 和 function 声明会被提升。在所在的作用域会被提升,不会扩展到其他的作用域。预编译后会顺序执行代码。

总之,当JavaScript引擎解析脚本时,它会在预编译期对所有声明的变量和函数进行处理,并且是先预声明变量,再预定义函数,以提高程序的执行效率!

2.运行阶段

在浏览器环境中,javascript引擎会按照 <script>标签代码块从上到下的顺序加载并立即解释执行。

最新回复(0)