其实V8引擎的C++代码是有100w+行的,通过他的架构我们可以了解到他是如何运行的。
V8引擎的包含哪些部分?他有哪些作用?
Parse是将Javascript代码转换为语法抽象树AST,原因是解释器并不直接认识Javascript代码,其实将Javascript代码直接转换为AST语法抽象树并不是只有在V8引擎中使用,在Babel和Vue源码中都要将Javascript代码转换成语法抽象树。如果有什么不明白的可以详细查看V8的Parse官方文档
Ignition是一个解释器,将抽象语法树AST转换成ByteCode字节码。同时还会收集一些TurboFan优化所需要的内容:比如说我们的字符类型,因为有了类型才能更精确的运算,如果我们的函数只执行一次的话,就会直接执行字节码ByteCode。如果有不懂的可以详细查看Ignition的执行官方文档
TurboFan是一个编译器,他可以将字节码编译成可以让CPU直接运行的机器码。就打个比方说,在一个函数被重复调用的时候,这个函数就会被直接标记为热点函数,那么就会直接被TurboFan转换为机器码,提高代码的运行效率。
但是呢还有一种情况,我们如果随意改变函数的传参类型,优化成机器码的函数就会重新去优化。重新回到字节码的状态。因为当参数类型变化了函数就不能正确的处理运算了。 如果有疑问的可以查看V8的TurboFan官方文档
V8引擎的官方解析图
我们来看一下V8引擎团队给出的官方解析图。

上图就是说我们parse解析成AST抽象语法树的过程。
- 首先将
Javascript代码进行Blink也就是把不同格式编码的数据转换成Stream,因为我们在编码的时候文件保存格式可以是ASCII,Latin1,UTF8等等好多编码格式。但是我们需要统一由Stream转换成UTF-16的编码格式。这样方便进一步处理成抽象语法树。 Scanner词法分析器是我们的语法分析器,把我们定义的变量,方法还有类做一下区分。将tokens进行预解析(Preparser)和解析(Parser)。从而生成抽象语法树AST,再由AST转换为字节码bytecode。最后生成CPU可以直接识别的机器码。
为什么需要预解析呢?那是因为在Javascript代码执行的过程中,函数里面的方法没必要在调用的时候每次被声明,这样可以提高执行效率。然后将函数里面的方法加载的时候都会进行预解析。
那么我们的JavaScript源码是如何被解析(Parse过程)的呢?
我们系统拿到javascript代码的时候会由Blink交给V8引擎,通过Stream处理不同字符编码的文件为UTF-16格式,再由与我们的Scanner进行词法分析从而转换为tokens,然后tokens会被解析和预解析为抽象语法树AST,接下来就会由V8引擎继续解析成字节码bytecode......
为什么需要预解析PreParser呢?
因为为了检测一下有没有语法错误,另一方面也可以对代码进行进一步优化。因为并不是所有的代码一开始都需要进行执行。都执行就会影响加载速度。V8引擎在这方面进行了优化,使用Lazy Parsing延迟解析,对于不必要的函数进行预解析,就是只解析暂时要用的内容,对于预解析函数的全量解析是在上级函数被调用的时候才会被全量解析。
比如我们在out()里面定义了一个in(),只有在out()被调用的时候,in()才会被全量解析。
当被解析成AST抽象语法树时,会通过Ignition将抽象语法树转换为字节码bytecode。然后字节码会序列化成机器码,当然也会反序列化回来,这要看方法的传参类型有没有改变......
V8引擎的解析图
如果有什么不懂的,可以仔细看这一张详细的图片。

感谢大家观看
@秋风于渭水 确实
[...]不同的浏览器存在兼容性问题的核心原因是不同的浏览器可能使用的是不同的浏览器内核。在现代化开发中,大多数的浏览器兼容性问题是可以通过工程化中的配置选项来解决的。1.比如browserslist可以配置目标的浏览器或者Node环境,然后在不同的工具中起作用,比如autoprefixer/babel/postess preset env等,在进行了正确的配置后,开发的Vue或者React项目在进行打包时[...]
[...]在BFC中,box会在垂直方向上一个挨着一个的排布垂直方向的间距由margin属性决定在同一个BFC中,相邻两个box之间的margin会折叠(collapse)在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的然后我们再看一下官方文档中如何说明的?总结BFC是什么?W3C文档讲:在标准流中,我们所有的盒子,不管是块级盒子还是行内盒子,它们都属于某一个FC格式化上下文,块级盒子属于BFC`块级格[...]
[...]什么是FC呢这里我们给出W3C给出的文档,FC文档FC的全称是FormattingContext,元素在标准流里面都是属于一个FC的。那么什么又是IFC,BFC呢?IFC行内元素的布局都属于Inline Formatting,inline level box都是在IFC中布局的BFCBFC英文全称是Block Formatting Context,也就是block level box都是在BFC中[...]
这确实是一个盲点,这个还是很有必要的,处理不好会导致网页内的元素出现抖动问题。
[...]我们知道,当浏览器在执行到script标签的时候,首先会停止构建DOM树,然后下载Javascript文件并且执行,当JavaScript脚本执行完毕之后才会继续解析HTML标签构建DOM树。为什么Javascript程序会这样做呢?原因是我们的Javascript的作用就是操作DOM并且可以修改DOM。如果我们等到HTML执行完成之后再去执行JavaScript就会造成严重的回流和重绘,尤其是现[...]
[...]async属性和defer属性目标一样它也是为了不让js阻塞DOM树的构建。不过他们两个还是有区别的。async让js脚本的下载和执行是独立的。浏览器不会因为async属性的script脚本的执行而阻塞,这一点和defer属性类似。然而async属性比较任性,只要脚本被浏览器下载完成之后就会立即执行,不会等待在DOMContentLoaded之前执行。所以它不能保证是在DOMContentLoad[...]
我热爱 旅游专栏。令人惊艳了解路线。
欣赏你的照片, 我明白, 世界很美。感谢 旅行灵感。
读起来像小说。继续保持 带来的灵感。