JS作为一门高级语言,代码给到浏览器或nodejs时是不能被底层CPU执行的,就需要通过JS虚拟机来实现代码编译和执行。V8最为广泛,采用了即时编译(JIT)的双轮驱动设计,混合了编译执行和解释执行2种方式
编译器(Compiler
),解释器(InterPerter
),抽象语法树(AST
),字节码(Bytecode
),即时编译器(JIT
)。
因为机器不能直接理解我们所写的代码,所以在执行程序之前,需要将我们所写的代码“翻译”成机器能读懂的机器语言。
解释型语言编写的程序:在每次运行时都需要通过解释器对程序进行动态解释和执行。JavaScript
属于解释型语言。
在解释型语言的解释过程中,同样解释器也会对源代码进行词法分析、语法分析,并生成抽象语法树(AST
),不过它会再基于抽象语法树生成字节码,最后再根据字节码来执行程序、输出结果。
- 生成抽像语法树和执行上下文。
比如AST
用于babel
,先将ES6
转为AST
,再将ES6
的AST
转为ES5
的AST
,最后利用ES5
的AST
生成JS
源代码。
生成AST
2个阶段:
(1)分词(词法分析)将源码拆成token
。var myName='思否'
。关键字var
、标识符myName
、赋值运算符=
、字符串思否
都是token
。
(2)解释(语法分析)将token
根据语法规则转成AST
。AST生成过程:先分词再解释。有了AST
,V8就可以为该段代码会成为可执行上下文。 - 生成字节码,有了
AST
和执行上下文,解释器Ignition
就会根据AST
生成字节码并解释执行字节码。一开始V8
是直接将AST
转为机器码的,因为机器码执行效率高,但是占内存,后来才引入了字节码。字节码是介于AST
和机器码之间的一种代码,字节码需要通过解释器转成机器码才能执行。 - 执行代码,第一次执行的字节码,解释器(
Ignition
)会逐条解释执行。如果有被执行多次的代码,编译器TurboFan
会把这段代码编译为机器码,并把编译后的机器码保存起来。当再次执行这段代码时,只用执行保存的机器码就行了。提升了执行效率,执行时间越久重复执行代码越多,被保存的编译机器码越多,不用编译就越快。被称为即时编译:字节码+解释器+编译器。
var myName='思否';
function foo(){ return 23 };
myName='segmentfault';
foo();
编译后:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。