JavaScript 引擎和 JavaScript 运行时有什么区别?

运行时和引擎经常被错误地认为是同一个东西。

您可能听说过“JavaScript 引擎”和“JavaScript 运行时”这两个术语可以互换使用,表示“运行 JavaScript 的程序”。它们经常通过引用 V8、Node.js 或其他相关程序组合来混合使用。但是,JavaScript 引擎和 JavaScript 运行时在范围和功能方面存在显著差异。理解这一差异是全面理解 JavaScript 语言的关键。

简单总结来说:JavaScript引擎实现ECMAScript标准,而JavaScript运行时环境在此基础上添加输入/输出等附加功能,并可根据需要定义API。

在展开讨论引擎与运行时之间有何区别之前,有必要先定义几个经常与引擎和运行时结合使用的术语:ECMAScript 和 JavaScript。

什么是 ECMAScript?

1996 年,Netscape 和 Sun Microsystems 与非营利性标准组织 Ecma International 接洽,商讨如何标准化 JavaScript。这项努力的成果是 ECMA-262,该规范于 1997 年发布,定义了 JavaScript 实现的工作方式。由于 Sun 不愿意捐赠 JavaScript 商标,该规范必须使用不同的名称,因此 ECMA-262 被命名为“ECMAScript 语言规范”。因此,ECMAScript 是 ECMA-262 中指定的语言的名称。

ECMAScript定义了JavaScript的核心功能,这些功能必须由符合规范的实现来提供,无论它们被嵌入到哪里(嵌入实现的程序被称为宿主)。即使在早期阶段,Netscape 也打算不仅在浏览器中使用 JavaScript,而且还在服务器上使用,而 ECMAScript 将作为这两种实现的核心。因此,ECMAScript 不包含任何与 Web 相关的功能,也不包含任何输入或输出数据的方式(此类功能必须由宿主提供)。这意味着 ECMAScript 包含标准全局类(例如ObjectArrayPromise),但不包含HTMLElementsetTimeoutfetch()

什么是 JavaScript?

“JavaScript”一词没有正式的定义,但人们普遍认为它是ECMAScript语言的一个超集。这意味着JavaScript除了实现ECMAScript之外,还实现了其他规范和其他功能。在其早期形式中,JavaScript被认为是ECMAScript加上基于Web的API,如文档对象模型(DOM)和基于浏览器的API,如 History API。如今,JavaScript被认为是ECMAScript加上任何其他宿主提供的API的任何组合。这包括针对浏览器的特定于Web的API和针对如Node.js等宿主的特定于服务器的API。

什么是 JavaScript 引擎?

通常所说的 JavaScript 引擎更准确地说应该是 ECMAScript 引擎,因为它们实现了 ECMA-262,没有任何(或太多)附加功能。JavaScript 引擎旨在嵌入到宿主中,而宿主又定义了用于输入和输出的附加功能。

最知名的 JavaScript 引擎是:

由于 JavaScript 引擎仅实现 ECMAScript 并且可以通过宿主进行扩展,因此它们可以在各种不同的运行时环境中使用。

什么是 JavaScript 运行时?

JavaScript运行时环境是一个ECMAScript宿主,意味着它是一个嵌入JavaScript引擎的程序。Chrome、Firefox、Edge、Safari、Node.js、Deno和Bun都是JavaScript运行时环境,因为它们都嵌入了JavaScript引擎,并定义了可通过JavaScript访问的额外功能。Web浏览器实现了DOM和其他Web API,而服务器端运行时环境则实现了文件系统访问功能。

对于 JavaScript 运行时可以添加哪些附加功能,没有任何规则;运行时开发人员可以自行决定。这就是为什么 Node.js、Deno 和 Bun 都以不同的方式实现文件系统,以及为什么 Deno 决定青睐 Web API,例如fetch()Node.js 最初决定实现自己的 HTTP 客户端(Node.js 此后也采用了fetch())。使JavaScript运行环境变得独一无二的,不仅仅是JavaScript的API,还有它们使用JavaScript引擎的方式。

例如,事件循环(允许运行时在运行 JavaScript 和执行其他任务之间切换的过程)未在 ECMA-262 中定义,因此未在任何 JavaScript 引擎中实现。每个 JavaScript 运行时都应实现自己的事件循环。Web 浏览器在其 HTML 规范中定义了自己的事件循环版本,但 Node.js 等服务器端运行时环境则定义了它们自己的事件循环。虽然事件循环不是JavaScript运行时环境的必需组件,但它通常出现在通用JavaScript运行时环境中。

总结

JavaScript引擎和JavaScript运行时环境是相关的,但并不完全相同。JavaScript引擎实现了ECMA-262标准中定义的ECMAScript。ECMA-262定义了JavaScript的核心功能,但不提供任何输入或输出功能。而JavaScript运行时环境是一个ECMAScript宿主,它嵌入了一个JavaScript引擎,并为其增加了输入和输出的附加功能,以及运行时所需的其他任何功能。这些附加功能可能包括Web浏览器中的DOM或服务器端运行时环境中的文件系统访问。运行时环境没有义务遵循其他标准,并且可以根据需要定义自己的API,这就是为什么Node.js、Deno和Bun都有各自不同的文件系统API的原因。

相关链接

  1. JavaScript 创建者思考过去和未来

  2. V8——Google 的开源 JavaScript 引擎

  3. SpiderMonkey - Firefox 的 JavaScript 引擎

  4. JavaScriptCore - Safari 的 JavaScript 引擎

  5. HTML 标准 - 事件循环

  6. Node.js - 事件循环、计时器和 process.nextTick()

  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端后花园

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值