JavaScript代码是如何被机器理解并执行的呢?
作为 JavaScript 开发者,通常我们不需要关心JavaScript引擎是如何执行代码的。但是,了解 JavaScript 引擎的工作原理,知晓它如何处理我们编写的 JS 代码、肯定是有益的。
注意:这篇文章讲述的原理,基于 Node.js 和 Chromium 的浏览器所使用的 V8 引擎。
HTML 解析器遇到script标签时,会从网络、缓存中以字节流的方式加载代码。此阶段,字节流解码器会负责将字节转为代码字符。
例如,字节流中的 0066 解码为 f,0075 解码为 u,006e 解码为 n,0063 解码为 c,0074 解码为 t,0069 解码为 i,006f 解码为 o,006e 解码为 n。结合起来便是: function! JavaScript 中的一个函数关键字,这时会将它做为JavaScript代码,并创建一个标记并发送给JS引擎。
JS引擎使用两个解析器:预解析器和解析器。为了减少加载网页所需的时间,引擎会尽量避免立即解析不必要的代码。预解析器处理可能稍后会使用的代码,而解析器则处理立即需要的代码!
如果某个函数只有在用户点击按钮后才会被调用,那么不必要立即编译这段代。如果用户最终点击了按钮并需要那段代码,它才会被发送到解析器。
解析器根据从字节流解码器接收到的代码创建节点:创建一个抽象语法树(AST)。
接下来,轮到解释器了!解释器遍历 AST,并根据 AST 包含的信息生成字节码。
一旦字节码完全生成,AST 就会被删除,从而释放内存空间。字节码已经是机器可以识别和处理的东西!
字节码速度很快。
但还可以更快。当字节码运行时,它可以检测某些行为是否经常发生,比如你多次调用一个函数:这时便可优化它,让它运行得更快:字节码与行为反馈数据一起被发送到优化编译器。优化编译器接从这些信息中生成高度优化过的字节码:机器码。
总结而言,JS代码变为机器可识别的整个过程是:
字节流 → JavaScript代码 → 抽象语法树(AST) → 字节码 → 机器码。