javascript 的 "on the fly" 编译实际上是如何工作的?

How actually works javascript's "on the fly" compilation?

我正在读 Kyle 的 "You don't know JS" 书 series/watch 他的讲座,他说,下面的代码:

var a = 2;
2();

Javascript 语言方面,第二行是错误的。它实际上在语法上是无效的。这不是 运行 时间问题;这是一个实际的作者时间问题。

所以在解释性语言中,如果我们纯粹 运行 一行一行地进行而不是多次传递 - 我们会先 运行 第一行,然后我们会发现那一行两个有问题,我们会抛出一个错误。

但是编译语言会说第二行的问题,它会在尝试 运行 第一行之前用那个错误标记你。

"So JavaScript, in that respect, is more a compiled language than an interpreted language, because JavaScript definitely does look at line two first before it's ever tried to run line one. It looked at line one to understand what line one was about, but it didn't run it. So when you put a program like this, if that was in a file and you loaded that up into a browser, line one would never run. You'd immediately get an error saying line two is invalid."


所以我在 chrome 的控制台中尝试了这段代码,令人惊讶的是它工作正常,我的意思是 a 变量是将被分配,如果我们稍后尝试 console.log(a) 它会打印“2”。

它是某种控制台的特定行为还是什么?

作者错了

第一:他的例子无效

2() 是——也许有点令人惊讶——不是 Javascript 中的语法错误!这是完全有效的 syntax;这不是您可以做的事情,因此它会在 运行 时间生成类型错误:

> console.log("test"); 2()
test
TypeError: 2 is not a function

这种错误不会阻止程序的编译和运行。正如您在成绩单中看到的那样,只有在到达无效调用时才会抛出错误;它之前的其他代码通常 运行s。

比较当我们引入一个真正的语法错误时会发生什么:

> console.log("test"); 1x
SyntaxError: Unexpected identifier

这实际上是一个语法错误——假定以 1 开头的 "word" 是一个数字,而数字中不能有 x —— 所以它防止整个表达式成为 运行。 console.log() 永远不会执行。


其次: 作者在错误的地方划定了 "interpreted" 和 "compiled" 语言之间的界限。

解析程序以弄清楚它的含义,并捕获任何语法错误,这与 "compiling" 不同。这是编译中必要的第一步,但不是全部。实际上,"compiled" 语言通常被定义为输入程序在 运行 之前被转换为本机可执行文件的语言。在这方面,Javascript显然是一种解释性语言。

如果我们采用作者对 "interpreted languages" 的定义,即程序一次性 运行,甚至不解析文件的其余部分,就几乎没有语言在那个类别中。 (唯一想到的是一些 shell 脚本语言。)