何为JavaScript引擎,带你揭开它神秘的面纱
发布时间:2021-09-03 10:58:29 已帮助:74人
何为JavaScript引擎,带你揭开它神秘的面纱
javascript是编程语言的一种,这个我相信很多人是知道的。但是他具体如何使用,能实现什么功能,就可能很少有人清楚了。
现在很多人认为java和javascript能做的工作差不多,就更是一种非常错误的认识。
最初,JavaScript只能在Web浏览器中运行,但是随着Node的出现,现在JavaScript也可以在服务端运行。虽然我们可能知道应该在何时何地去使用它,但是我们真的了解这些脚本执行的背后发生了什么吗?
如果您觉得自己对JavaScript引擎有了一些了解的话,可以先给自己鼓个掌,但不要急着关掉本文,我相信阅读完成后您仍然可以从中学到一些东西。
JavaScript是一门高级语言,但是最终计算机能理解只有1和0。那么我们编写的代码是如何被计算机理解的呢?掌握所学编程语言的基础知识将让您能编写出更好的代码。在本文中,我们仅探讨一个问题:JavaScript是如何工作的?
下面让我们进入正题~
JavaScript引擎
这是本文将要探索的主要内容,它负责使计算机理解我们编写的JS代码。JavaScript引擎是一种用于将我们的代码转换为机器可读语言的引擎。如果没有JavaScript引擎,您编写的代码对计算机来说简直是一堆“胡言乱语”。不仅仅是JavaScript,其他所有编程语言都需要一个类似的引擎,来将这些“胡言乱语”转换成对计算机有意义的语言。
目前有多种JavaScript引擎在可供使用。您可以在Wikipedia上查阅所有可用的JavaScript引擎。它们也被称为ECMAScript引擎,这样叫的具体原因会在下文中提及。下面是一些我们日常可能会用到的JavaScript引擎:
·Chakra,Microsoft IE/Edge
·SpiderMonkey,FireFox
·V8,Chrome
除此之外的其它引擎,可以自行搜索了解。接下来,我们将深入研究这些引擎,以了解它们是如何翻译JavaScript文件的。
我们已经知道了引擎是必须的,由此可能不禁会想:
是谁发明了JavaScript引擎?
答案是,任何人都可以。它只是分析我们的代码并将其翻译的另一种语言的工具。V8是最受欢迎的JavaScript引擎之一,也是Chrome和NodeJS使用的引擎。它是用C++(一种底层语言)编写的。但是如果每个人都创造一个引擎,那场面就不是可控范围内的了。
因此,为了给这些引擎确立一个规范,ECMA的标准诞生了,该标准主要提供如何编写引擎和JavaScript所有功能的规范。这就是新功能能在ECMAScript 6、7、8上实现的原因。同时,引擎也进行了更新以支持这些新功能。于是,我们便可以在开发过程中检查了浏览器中JS高级功能的可用性。
我们输入的代码将通过以下阶段
1.Parser
2.AST
3.Interpreter生成ByteCode
4.Profiler
5.Compiler生成优化后的代码
别被上面的流程给唬住了,在几分钟后您将了解它们是协同运作的。
在进一步深入这些阶段之前,您需要先了解Interpreter和Compiler的区别。
Interpreter VS Compiler
通常,将代码转换成机器可读语言的方法有两种。我们将要讨论的概念不仅适用于JavaScript,而且适用于大多数编程语言,例如Python,Java等。
·Interpreter逐行读取代码并立即执行。
·Compiler读取您的整个代码,进行一些优化,然后生成优化后的代码。
当您阅读完上面的推荐文章后,您可能已经了解到Babel实际上是一个JS Compiler,它可以接收您编写的新版本JS代码并向下编译为与浏览器兼容的JS代码(旧版本的JS代码)。
Interpreter和Compiler的优缺点
·Interpreter的优点是无需等待编译即可立即执行代码。这对在浏览器中运行JS提供了极大的便利,因为所有用户都不想浪费时间在等待代码编译这件事上。但是,当有大量的JS代码需要执行时会运行地比较慢。还记得上面例子中的那一小段代码吗?代码中执行了1000次函数调用。函数add被调用了1000次,但他的输出保持不变。但是Interpreter还是逐行执行,会显得比较慢。
·在同样的情况下,Compiler可以通过用2代替循环(因为add函数每次都是执行1+1)来进行一些优化。Compiler最终给出的优化代码可以在更短的时间内执行完成。
综上所述,Interpreter可以立即开始执行代码,但不会进行优化。Compiler虽然需要花费一些时间来编译代码,但是会生成对执行时更优的代码。
好的,Interpreter和Compiler必要知识我们已经了解了。现在让我们回到主题——JS引擎。
因此,考虑到编译器和解释器的优缺点,如果我们同时利用两者的优点,该怎么办?这就是JIT(Just In Time)Compiler的用武之地。它是Interpreter和Compiler的结合,现在大多数浏览器都在更快,更高效地实现此功能。同时V8引擎也使用此功能。
1.Parser是一种通过各种JavaScript关键字来识别,分析和分类程序各个部分的解析器。它可以区分代码是一个方法还是一个变量。
2.然后,AST(抽象语法树)基于Parser的分类构造树状结构。您可以使用AST Explorer查看该树的结构。
3.随后将AST提供给Interpreter生成ByteCode。如上文所述,ByteCode不是最底层的代码,但可以被执行。在此阶段,浏览器借助V8引擎执行ByteCode进行工作,因此用户无需等待。
4.同时,Profiler将查找可以被优化的代码,然后将它们传递给Compiler。Compiler生成优化代码的同时,浏览器暂时用ByteCode执行操作。并且,一旦Compiler生成了优化代码,优化代码则将完全替换掉临时的ByteCode。
5.通过这种方式,我们可以充分利用Interpreter和Compiler的优点。Interpreter执行代码的同时,Profiler寻找可以被优化的代码,Compiler则创建优化的代码。然后,将ByteCode码替换为优化后的较为底层的代码,例如机器代码。
这仅意味着性能将在逐渐提高,同时不会有阻塞执行的时间。
关于ByteCode
作为机器代码,ByteCode不能被所有计算机理解及执行。它仍然需要像虚拟机或像Javascript V8引擎这样的中间件才能将其转换为机器可读的语言。这就是为什么我们的浏览器可以在上述5个阶段中借助JavaScript引擎在Interpreter中执行ByteCode的原因。
JavaScript是一门解释型语言吗?
JavaScript是但不完全是一门解释型语言。Brendan Eich最初是在JavaScript的早期阶段创建JavaScript引擎“SpiderMonkey”的。该引擎有一个Interpreter来告诉浏览器该怎么执行代码。但是现在我们的引擎不仅包括了Interpreter,还有Compiler。我们的代码不仅可以被转换成ByteCode,还可以被编译输出优化后的代码。因此,从技术上讲,这完全取决于引擎是如何实现的。
以上我们简短的介绍了一下JavaScript引擎的整体工作原理,也是十分简单易懂的,虽然可能对这个项目并不是十分了解的情况下也能写出代码,但是如果了解了一些幕后知识,写出的代码将更为优秀。