【动画演示】JavaScript 引擎运行原理

做者:Lydia Halliejavascript

译者:前端小智前端

来源: devjava

点赞再看,养成习惯
git


本文 GitHub:github.com/qq449245884… 上已经收录,更多往期高赞文章的分类,也整理了不少个人文档,和教程资料。欢迎Star和完善,你们面试能够参照考点复习,但愿咱们一块儿有点东西。github

JavaScript 很酷,可是 JS 引擎是如何才能理解咱们编写的代码呢?做为 JS 开发人员,咱们一般不须要本身处理编译器。然而,了解 JS 引擎的基础知识并了解它如何处理JS代码,并将其转换成机器可以理解的东西,绝对是个有益无害的事情。面试

注意:本文主要基于 Node.js 和基于 Chrome 的浏览器使用的 V8 引擎。浏览器

HTML解析器遇到带有源代码的script标签。 来自此源的代码从网络,缓存或已安装的服务工做程序中加载。 响应是将请求的脚本做为字节流,由字节流解码器负责。字节流解码器在下载字节流时对其进行解码。缓存

字节流解码器从已解码的字节流中建立令牌。例如,0066解码为f, 0075u, 006en, 0063c, 0074t, 0069i, 006fo, 006en,后面跟一个空格。就像JS中的function,这是 JS 中的一个保留关键字,它会建立一个标记,并将其发送给解析器。对于字节流的其他部分也是如此。bash

该引擎使用两个解析器:预解析器(pre-parser)解析器(parser)。预解析器只提早检查标记,以查看是否有语法错误。这能够减小发现代码中的错误所需的时间,不然解析器稍后就会发现这些错误。网络

若是没有错误,解析器将根据从字节流解码器接收到的标记建立节点。使用这些节点,它建立了一个抽象语法树,即AST

接下来,轮到解释器(interpreter)了。遍历AST并根据AST包含的信息生成字节码的解释器。一旦字节码彻底生成,AST就会被删除,从而清除内存空间。最后,生成的机器码就能够在电脑上运行了。

虽然字节码很快,但它能够更快。当这个字节码运行时,将生成信息。它能够检测某些行为是否常常发生,以及所使用数据的类型。也许已经调用一个函数几十次了:如今是时候优化它了,这样它会运行得更快!

字节码与生成的类型反馈一块儿发送到优化编译器(ptimizing compiler)。 优化的编译器接收字节码和类型反馈,并根据这些信息生成高度优化的机器码。

JS 是一种动态类型语言,这意味着数据类型能够不断变化。若是 JS引擎每次都要检查某个值的数据类型,那么速度会很是慢。

相反,JS 引擎使用一种称为**内联缓存(inline caching)**的技术。它将代码缓存在内存中,但愿未来它会以相同的行为返回相同的值.假设某个函数被调用100次,而且到目前为止老是返回相同的值。它将假设在第101次调用它时也会返回这个值。

假设咱们有如下函数sum,(到目前为止)每次都使用数值做为参数来调用它:

function sum(a, b) {
    return a + b
}
sum(1,2)
复制代码

执行结果为 3。 下次调用它时,它将假定咱们再次使用两个相同数字对其进行调用。

若是假投,那么就不须要动态查找,只须要使用存储在特定内存槽中的结果,该槽已经有一个引用。不然,若是假设不正确,它将反优化代码并恢复到原始字节码,而不是优化后的机器码。

例如,下一次调用它时,咱们传递的是字符串而不是数字。由于 JS 是动态类型的,因此这样作不会有任何错误。

function sum(a, b) {
    return a + b
}
sum('1',2)
复制代码

这意味着数字2将被强制转换成字符串,而函数将返回字符串'12'。它返回执行解释的字节码并更新类型反馈。

我但愿这篇文章对你有用!固然,在这篇文章中尚未涉及到引擎的更多部分(JS堆,调用堆栈,等等),后续会继续分享。若是你对 JS 的内部机制感兴趣,强烈建议本身能够作一些研究,V8 是开源的,而且有一些很棒的文档说明它是如何工做的。


dev.to/lydiahallie…

代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具 Fundebug


交流

干货系列文章汇总以下,以为不错点个Star,欢迎 加群 互相学习。

github.com/qq449245884…

我是小智,公众号「大迁世界」做者,对前端技术保持学习爱好者。我会常常分享本身所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,便可看到福利,你懂的。

相关文章
相关标签/搜索