非常抱歉我问了这个愚蠢的问题,但我对此感到困惑。
我一直在阅读一本名为you don't know JS yet
的书籍,该书提到:
JS最准确地描述是编译语言。
他们用一些例子进行了解释,对我来说这很有道理。
但是当我在互联网上搜索时,大多数人都认为JS是一种解释性语言。 我读到了JS引擎使用许多技巧来处理JS程序,例如JIT、热重新编译等。
那么我应该把Javascript视为既编译又解释的语言吗?
非常抱歉我问了这个愚蠢的问题,但我对此感到困惑。
我一直在阅读一本名为you don't know JS yet
的书籍,该书提到:
JS最准确地描述是编译语言。
他们用一些例子进行了解释,对我来说这很有道理。
但是当我在互联网上搜索时,大多数人都认为JS是一种解释性语言。 我读到了JS引擎使用许多技巧来处理JS程序,例如JIT、热重新编译等。
那么我应该把Javascript视为既编译又解释的语言吗?
更新:
1995-96年,Brendan Eich创建了第一个JS引擎——spider-monkey(仍在Mozilla Firefox中使用),最初JavaScript是为浏览器设计的。因此,来自服务器的任何文件都可以快速解释并由浏览器显示。
解释器是这样做的最佳选择,因为解释器逐行执行代码并立即显示结果。
但随着时间的推移,性能成为一个问题,它变得越来越慢。解释器的问题在于当您在循环中运行相同的代码时:
const someCalculation = (num1, num2) => {
return num1 + num2;
};
for (let i = 0; i < 10000; i++) {
someCalculation(5, 6); // 11
}
它可能会变得非常慢。
因此,最好的选择是引入编译器,
这实际上对我们有所帮助。它需要更长的启动时间,因为它必须在开始时经过编译步骤-浏览我们的代码,理解它并将其吐出到另一种语言中。但编译器会很聪明。当它看到像上面那样的代码(我们循环并具有相同的输入,返回相同的输出),它实际上可以简化此代码,并且可以用函数的输出替换此函数而不是多次调用此函数。类似于这样的东西。
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代码执行速度将逐渐提高,因为分析器和编译器不断更新和更改我们的字节码,以尽可能高效。因此,解释器允许我们立即运行代码,而分析器和编译器允许我们在运行时优化代码。
现在让我们得出一些结论:
既然我们知道JS引擎在内部是如何工作的,作为程序员,我们可以编写更多优化的代码 - 代码可以比我们常规的Javascript更快地被编译器接受和运行。然而,
我们需要确保不要让编译器混淆-因为编译器并不完美,它可能会犯错误,并尝试优化恰好相反的代码。如果它犯了错并且做了一些意外的事情,它会执行称为取消优化的操作,这需要更长的时间才能将其还原回解释器。
现在有一个大问题: Javascript是一种解释性语言吗?
回答:是的,最初当Javascript第一次出现时,您有一个Javascript引擎(例如由Brenden Eich创建的Spider-Monkey),该引擎将Javascript解释为字节码,并且该Javascript引擎能够在我们的浏览器内运行,告诉我们的计算机应该做什么。当有人说Javascript是一种解释性语言时,是有一定道理的,但这取决于实现方式。您可以制作一个Javascript引擎的实现,它仅编译。从技术上讲,这都取决于实现方式。
Javascript最初是一种解释型语言。第一次遇到代码时,它会逐个读取标记并根据规范精确地执行它们。这是第0级。
如果某段代码经常被执行,比如说100次(具体数字取决于浏览器),则认为它是“热”的。浏览器将标记化和基本操作预先计算到稍微快一些的字节码中。在这个阶段,不做任何假设,字节码与原始代码完全等效。这是第1级。
如果代码被执行得更频繁,比如说10,000次,并且参数的类型始终相同,则可以执行进一步的编译步骤。许多JavaScript运算符根据类型执行完全不同的操作。每个运算符都有一些逻辑来检查要执行的运算符变体(例如添加或连接)。不同类型的对象需要分配不同数量的内存。在函数顶部执行一次类型检查并一次性分配所有内存要快得多。这是第2级。
根据浏览器的不同,可能会有更多的优化级别,通常是通过对参数进行更严格的假设。可能有更有效的整数加法。当然,如果您使用不同的变量类型调用函数,则浏览器必须再次执行未经优化的原始JS。
所有这些都是在幕后发生的,作为程序员,您很可能永远不必担心这个问题。优化永远不会改变程序的“大O”速度,这通常是导致大多数慢软件的原因。通过确保最常调用的函数的参数类型一致,您可能能够稍微提高速度,但不值得麻烦。