javascript - 为什么JS是解释型的而不是编译型的?

标签 javascript node.js compilation interpretation

我读了很多关于解释、编译、即时编译等的东西,但是我还没有找到关于为什么 JS 作为解释性语言被创建以及为什么仍然没有能力的明确解释编译js代码。

我有一些想法,但我不确定:

  1. 如果浏览器可以执行(或只是传递给操作系统)二进制代码,这将是一个很大的漏洞,因为任何命令都可以注入(inject)到二进制代码中(例如,从文件系统中删除所有文件)。如果这是真的,是否可以教浏览器以某种方式验证二进制代码?对于后端来说这不是问题。那么,为什么NodeJS不能执行编译后的JS(PHP、Python也是如此,为什么它们是解释型的)?
  2. 无法对二进制代码进行优化。真的是这样吗?优化的解释型 js 比编译(二进制)js 更快吗?
  3. 不同的CPU(架构)需要不同的二进制代码。这意味着不可能为任何客户端生成通用的二进制代码。这就是为什么 WebAssembly 模块使用一些中间代码?再说一次,为什么不对后端使用编译代码?

如果有人可以解释上述一些或任何其他原因,我将非常感激。

最佳答案

首先我们要说的是,除非您参与过 Javascript 早期的设计讨论,否则我们没有人真正“知道”原因。我们能做的最好的事情就是尝试根据他们的目标和选择来推断为什么会做出某些选择。

如果您查看网页中 Javascript 的原始设计要求,您会看到如下内容:

  1. 必须在多种平台上运行。
  2. 必须能够轻松嵌入 HTML 页面。
  3. 编程必须简单。
  4. 最初并不是一个需要最大限度提高执行性能的环境。
  5. 不是 Java。

让我们看看这些...

关于 #1,好吧,在很多平台上运行意味着它无法编译为 native 机器代码 - 就这样。它可以编译为通用字节代码,如 Java 或 webAssembly,但请继续阅读其他要求。

关于#2,它希望能够嵌入网页中,以便您可以执行以下操作:

<div onclick='alert("hi")'>Click me</div>

然后,将预先编译的代码放入其中是相当困难的。您可能必须编译整个网页。这创建了一个全新的范例和浏览器(需要预编译的代码和 HTML)。虽然世界最终可能会变成这样,但这当然不是一个容易的方法(需要重做浏览器)。

关于#3,“编程简单”,人们普遍认为,解释型“脚本”比需要编程环境、编译器设置和一些构建工具的语言更容易上手。做简单的事情更快更简单。

关于#4,“性能”。在Javascript的早期,它是一种辅助语言,帮助向网页添加一些客户端逻辑。最初的目标比今天使用的 Javascript 简单得多。我相当怀疑是否有人设想需要预编译语言来实现其最初的目标。因此,保持简单并采用更简单的方法来实现目标。

关于 #5:“不是 Java”。 Java 是当时众所周知的工具。但是,Java 并不是 super 简单,需要预编译,有 IP 负担等等……因此,Javascript 天生就是 C 和 Java 开发人员都熟悉的东西,但对于新手来说要简单得多。轻松做简单的事情。


对于像nodejs这样的环境,他们实际上可以有一个预编译步骤,但是nodejs的早期设计者决定使用开源的V8 Javascript引擎,而不是制作自己的Javascript引擎。另外,在服务器世界中,您的代码通常在服务器启动时加载一次,V8 无论如何都会将其编译为 native 代码和字节代码的组合,因此要求开发人员预编译它并不一定会给您带来很多麻烦。这就是 Javascript 现在实际编译的重要之处,它只是在加载时编译,而不需要开发人员预编译。

现在,如果您想在预编译步骤中享受类型检查的好处,您可以使用 TypeScript 并将其预编译为 Javascript。

关于javascript - 为什么JS是解释型的而不是编译型的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69875696/

相关文章:

javascript - Material-UI TextField 上下文脏

javascript - 使用 Node 使用用户 ID 在 github 上创建要点

javascript - node.js promise : then() of promise nested inside a then() chain doesn't get resolved

c++ - 我应该将许多功能放在一个文件中吗?或者,或多或少,每个文件一个函数?

c++ - 找不到-lMagick++-6.Q16

javascript - 按一定顺序分隔数组中的字符串

javascript - 如何使用 html5 重置视频

node.js - 当用户输入错误的电子邮件时,为什么交易失败并已回滚

c - wedit lcc-win32 中程序 "is not up to date"执行错误

javascript - 无法动态转译 ES 模块 System.config({ transpile : 'transpile-module' })