JS代码如何被JS引擎执行
在介绍这个之前,首先先得了解编译器和解释器
编译器和解释器
众所周知,JS语言是一门高级解释型语言,即写出来是不能被机器直接执行的,需要通过解释器来一行一行将JS代码转换成字节码,再经操作系统交给CPU,来一个指令一个指令执行。不只是JS,所有的高级语言都需要通过 编译器/解释器 ,编译/解释后,转换成机器代码才能由CPU来运行
编译器和解释器就是把高级语言代码转换为机器代码的工具
下面简单说明一下编译和解释的过程
- 编译
编译器会依次对源代码进行词法分析、语法分析、生成抽象语法树AST、然后优化代码,最后生成CPU能够理解的机器代码,如果编译成功将会生成一个可执行目标文件,windows使用可移植可执行格式(Portable Executable,PE),MacOS使用 Mach-O 格式,现代 linux 和 unix 使用可执行可链接格式(Executable and Linkable Format,ELF) - 解释
解释器会对源代码进行词法分析、语法分析,并生成抽象语法树 AST,不过它不会直接生成CPU能够直接执行的机器代码,而是基于AST生成字节码,最后根据字节码来执行程序、输出结果。
浏览器中的JS代码,一般交由浏览器中的JS引擎来执行。下面主要介绍 V8 引擎。
V8 引擎 是怎样执行一段JS代码
V8为了提高JS的执行效率,采取了即时编译技术(JIT)ignition、TurboFan 分别是 V8中的 解释器、编译器的名字
下面重点介绍 V8中 的 JIT 技术
在经过前面通用的词法分析、语法分析生成抽象语法树AST,再经由 Ignition 解释器转换成字节码后
- 一般来说,V8引擎会逐行解释字节码执行
- 但如果发现有 热点代码,即这段代码被重复执行了很多次,这段代码就会被引擎识别为 热点代码,然后引擎中的 TurboFan 编译器就会把这段热点代码的字节码直接编译成可以直接由CPU来执行的机器码
- 当再次执行热点代码的时候,就可以直接使用这段代码的机器码来执行,从而大幅提高JS代码的执行效率
JIT即时编译技术是一项很热门的技术,Java和Python的虚拟机也都是基于这种技术来实现的,其本质是利用了局部性原理来大幅提高性能,在计算机系统的很多地方都能看到局部性原理,比如计算机的存储体系结构就是在大幅降低了成本之后,依然能够保持一个较高的性能和较大的存储空间。
在理解了JS是怎样被JS引擎执行后,可以利用JIT技术来写出一些高性能的JS代码,比如尽可能多的复用JS代码。