繁体   English   中英

JavaScript 是编译型还是解释型语言,还是两者兼而有之?

[英]JavaScript is compiled or interpreted language or both?

对于这个愚蠢的问题,我很抱歉,但我对此感到困惑。

我一直在读一本you don't know JS yet的书,书中说

JS 被最准确地描述为一种编译语言。

他们用一些例子解释,这对我来说很有意义

但是当我在 inte.net 上搜索时。 大多数人认为 JS 是一种解释型语言。 我读到 JS 引擎使用多种技巧来处理 JS 程序,例如 JIT、热重新编译。

那么我是否应该将 Javascript 视为编译语言和解释语言?

更新:

当 JavaScript 在 1995-96 年首次出现时,Brendan Eich 创建了第一个名为 spider-monkey 的 JS 引擎(仍在 Mozilla Firefox 中使用)。 此时创建了 JavaScript,牢记浏览器。 这样来自服务器的任何文件都会被浏览器快速解释和显示。

Interpreter 是这样做的最佳选择,因为 Interpreter 逐行执行代码并立即显示结果。

但随着时间的推移,性能成为一个问题,它变得越来越慢。 Interpreters 的问题在于,当您在这样的循环中一遍又一遍地运行相同的代码时:

const someCalculation = (num1, num2) => {
  return num1 + num2;
};

for (let i = 0; i < 10000; i++) {
  someCalculation(5, 6); // 11
}

它会变得非常非常慢。

所以最好的选择是引入编译器,

这实际上对我们有帮助。 启动需要更多时间,因为它必须通过开始的编译步骤 go - Go 通过我们的代码,理解它并将其吐出到另一种语言中。 但是编译器足够聪明。 当它看到上面的代码(我们循环并且它有相同的输入,返回相同的输出)时,它实际上可以简化这段代码,而不是多次调用这个 function 它可以只用 output 替换这个 function function。像这样的东西。

const someCalculation = (num1, num2) => {
  return num1 + num2;
};

for (let i = 0; i < 10000; i++) {
  11; // And it will  not call someCalculation again and again.
}

因为编译器不会为该循环中的每次传递重复翻译,所以从中生成的代码实际上更快。

编译器所做的这些类型的编辑称为优化

因此 Javascript 将解释器和编译器结合起来,获得了世界上最好的。 因此,浏览器开始混合称为 JIT 编译器的编译器以进行即时编译,以使引擎更快。

V8引擎

在图像中,您可以看到一个分析器,它监视重复的代码并将其传递给编译器以进行代码优化。

这意味着我们输入引擎的 Javascript 代码的执行速度将逐渐提高,因为 Profiler 和 Compiler 会不断更新和更改我们的字节代码,以尽可能提高效率。 因此,Interpreter 允许我们立即运行代码,而 Profiler 和 Compiler 允许我们在运行时优化此代码。

现在让我们得出一些结论:

现在我们知道 JS 引擎是如何工作的,作为程序员,我们可以编写更多优化代码——编译器可以采用并运行它的代码比我们的常规 Javascript 更快。但是

我们需要确保我们不会混淆这个编译器——因为编译器并不完美,它可能会出错,并且它可能会尝试优化恰恰相反的代码。 如果它犯了一个错误并且它做了一些意想不到的事情,它会做一些叫做去优化的事情,这需要更长的时间才能将它恢复到解释器。

现在是大问题: Javascript 是一种解释语言吗?

答案:是的,最初当 Javascript 首次出现时,您有一个 Javascript 引擎,例如由 Brenden Eich 创建的 spider-monkey- 将 javascript 解释为字节码,并且这个 Javascript 引擎能够在我们的浏览器内部运行以告诉我们的计算机要做什么做。

但是现在事情发生了变化,我们不仅有解释器,我们还使用编译器来优化我们的代码。 所以,这是一个普遍的误解。

当有人说 Javascript 是一种解释型语言时,是的,它有一定道理,但这取决于实现。 您可以实现 Javascript 引擎,也许只能编译。 从技术上讲,这一切都取决于实施。

Javascript 最初是一种解释型语言。 当它第一次遇到一段代码时,它会一个一个地读取标记并完全按照规范执行它们。 这是 0 级。

如果一段代码经常执行,比方说 100 次(确切的数字取决于浏览器)它被认为是“暖”。 浏览器将标记化和基本操作预先计算为稍快的字节码。 在这个阶段,不做任何假设,字节码完全等同于原始代码。 这是 1 级。

如果代码执行得更频繁,比方说 10,000 次并且参数的类型始终相同,则可以执行进一步的编译步骤。 许多 javascript 运算符根据类型做截然不同的事情。 每个运算符都有一些逻辑来检查要执行的运算符的变体(例如添加或连接)。 还需要将不同数量的 memory 分配给不同类型的对象。 在 function 的顶部执行一次类型检查并立即分配所有 memory 如果更快的话。 这是 2 级。

根据浏览器的不同,可能会有更多的优化级别,通常是通过对参数做出更严格的假设。 对于整数可能有更有效的加法。 当然,如果你用不同的变量类型调用 function,浏览器必须再次执行未优化的原始 JS。

实用建议

这一切都发生在幕后,作为一名程序员,您很可能永远不必担心这一点。 优化永远不会改变程序的大 O 速度,这通常是大多数软件运行缓慢的原因。 您可以通过确保最常调用的函数的参数类型一致来略微提高速度,尽管这还不够值得麻烦。

检查MDN

这是您获得最准确信息的地方
在该主题上引用MDN

JavaScript (JS) 是一种轻量级、解释型或即时编译型编程语言

基本上,由于 JS 在多种环境中使用,它可以是其中之一。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM