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

Ale*_*pun 2 javascript compilation interpretation node.js

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

我有一些想法,但我不确定其中任何一个:

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

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

jfr*_*d00 5

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

如果你看看网页中 Javascript 的原始设计要求,你会看到这样的东西:

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

让我们看看这些...

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

关于#2,它希望能够嵌入网页中,这样你就可以执行以下操作:

<div onclick='alert("hi")'>Click me</div>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


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

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