JavaScript - Engine 和 Runtime(引擎和运行时)
JavaScript 引擎是一种执行 JavaScript 代码的计算机软件。它负责将人类可读的 JavaScript 代码转换为计算机硬件能够理解的指令。
当 JavaScript 代码在浏览器中执行时,它不会直接与计算机硬件交互。相反,它会与 JavaScript 引擎进行通信,JavaScript 引擎充当系统和代码之间的接口。
尽管每个浏览器都有自己的 JS 引擎,但 Google 的 V8 引擎是最常用的 JS 引擎。V8 引擎为用于构建服务器端应用程序的 Node.js 和 Google Chrome 提供支持。
在本章中,您将详细了解 JS 引擎是什么以及它是如何运作的 -
JavaScript 引擎如何工作?
任何 JS 引擎中都始终存在调用堆栈和堆。借助执行上下文,我们的代码在调用堆栈中运行。此外,堆是一个非结构化的内存池,用于存放应用程序所需的所有数据。
既然您知道代码的执行位置,下一步就是了解如何将其编译成机器码,以便稍后运行。但我们首先来回顾一下编译和解释。
编译 vs 解释
在编译过程中,所有代码都会并发地转换为机器码,并存储在计算机可以运行的二进制文件中。
在解释过程中,解释器会逐行执行源代码。在程序运行时,代码仍然需要转换为机器码,但这次是逐行执行。
过去,JS 只是一种解释型语言。但是,现代 JS 引擎现在使用的是"即时"编译,即编译和解释相结合的编译方式。
使用 JIT 编译时,所有代码都会并发地转换为机器码并立即运行。
您可能想知道 JIT 和编译之间的区别。一个显著的区别是,机器码在编译后保存在一个可移植文件中。编译过程结束后无需着急,您可以随时运行它。
但是,使用 JIT 时,机器码必须在编译过程完成后立即执行。
JIT 和 JavaScript
让我们看看 JIT 在 JavaScript 中的具体工作原理。
因此,当一段 JavaScript 代码进入引擎时,第一步就是对其进行解析。
在解析过程中,代码会被转换为一种称为 AST(抽象语法树)的数据结构。其工作原理是,首先将每行代码分解成对语言来说重要的部分(例如,const 或 function 关键字),然后将所有这些部分以结构化的方式保存到树中。
此阶段还会判断是否存在语法错误。然后,生成的树将用于生成机器码。
下一个阶段是编译。引擎获取抽象语法树 (AST) 并将其编译为机器码。由于使用了 JIT,机器码随后会被立即执行;请记住,此执行发生在调用堆栈上。
但这并非终点。当代 JavaScript 引擎为了尽可能快地运行程序,会生成浪费资源的机器码。然后,引擎获取预编译的代码,并在程序运行时对其进行优化和重新编译。所有这些优化都在后台进行。
到目前为止,您已经了解了 JS 引擎及其幕后的工作原理。让我们来看看什么是 JavaScript 运行时,尤其是浏览器运行时。
JavaScript 引擎列表
以下是可用的 JavaScript 引擎列表 -
| 浏览器 | JavaScript 引擎名称 |
|---|---|
| Google Chrome | V8 |
| Edge (Internet Explorer) | Chakra |
| Mozilla Firefox | Spider Monkey |
| Safari | JavaScript Core Webkit |
让我们简要了解一下上表中提到的每个引擎 -
V8:由 Google 为 Chrome 开发。它通过加速 JavaScript 执行来提升网站和应用程序的用户体验。此外,V8 通过收集多余信息来管理内存,并使在服务器端(例如在 Node.js 中)使用 JavaScript 变得更加容易。
Chakra:Chakra 由 Microsoft 为 Internet Explorer 开发。它通过在单独的 CPU 核心上运行脚本来加速 JavaScript 运行,并允许浏览器同时执行其他操作。
SpiderMonkey:Netscape 的 Brendan Eich 开发了第一个 JavaScript 引擎 SpiderMonkey,目前由 Mozilla 为 Firefox 维护。由于它是开源的,任何人都可以使用或修改它。
WebKit:WebKit for Safari 由 Apple 开发,并被 iOS 设备、Kindle 和 PlayStation 使用。WebKit 除了显示网页外,还管理历史记录和来回导航等常用浏览器功能。
什么是 JavaScript Runtime(运行时)?
JavaScript (JS) 运行时是用于执行 JavaScript 代码的完整环境。它由许多组件组成,这些组件协同工作,帮助 JavaScript 应用程序顺利运行。当我们谈论 JS 运行时时,我们通常指的是不仅仅是执行代码的完整生态系统。
根据 JavaScript 的执行位置(在 Web 浏览器中还是在带有 Node.js 的服务器上),运行时可能包含其他特定于环境的功能。例如,在浏览器中,可以有管理浏览器事件、访问 DOM 以及与浏览器特定功能交互的功能。
目前,我们只介绍浏览器中的 JavaScript 运行时。JS 运行时可以想象成一个大盒子,包含在浏览器中运行 JavaScript 所需的所有组件。
JS 引擎是任何 JS 运行时的核心。然而,仅有引擎是不够的。良好的功能需要 Web API。
JS 运行时,尤其是在 Web 浏览器中使用的运行时,包含扩展基本 JavaScript 语言功能的 Web API。这些 API 包括与文档对象模型 (DOM)、XMLHttpRequest(用于发送 HTTP 请求)、计时器等的交互。
Web API 扩展了 JavaScript 的功能,使其能够与浏览器环境交互并执行诸如更改网页结构、处理用户事件和发送网络请求等活动。
因此,Web API 基本上是引擎提供的功能,不属于 JavaScript 语言。JavaScript 通过 window 对象访问这些 API。
JavaScript 中的异步操作(例如接收用户输入或执行网络查询)会使用回调函数。这些例程被放置在回调队列中等待执行。回调队列以有序的方式管理异步任务。
为了响应特定事件,我们可以将事件处理程序方法附加到 DOM 事件(例如按钮)。这些事件处理程序函数也称为回调函数。因此,当点击事件发生时,回调函数将被调用。

