为什么以及什么时候会立即忽略变量声明,并在后续查询中覆盖函数声明?

Luc*_*tar 5 javascript

在遵循Kyle Simpson 在Pluralsight上的Advanced JavaScript 时,我遇到了这段代码,它应该证明函数声明变量声明之前得到(预)编译:

foo();
var foo = 2;
function foo() { console.log("bar"); }
function foo() { console.log("foo"); }
Run Code Online (Sandbox Code Playgroud)

(请注意,上面的代码要么输入一行有空格而不是换行符,要么使用SHIFT+ENTER防止在输入整个代码之前立即执行。)在Node中输入上面整个代码的立即结果或 (Chrome) 控制台(并按 Enter 键)是:

  foo                                                                                                   
< undefined  
Run Code Online (Sandbox Code Playgroud)

解释 Kyle 的解释,第一个function foo声明被第二个覆盖,因此foo输出到控制台,并且由于foo已经声明为函数,var foo因此(预)编译器忽略该声明。

眼前的结果支持了理论忽略,然而,随后的调查foofoo()展示一个不同的故事:

> foo                                                                                                   
2                                                                                                       
> foo()                                                                                                 
Uncaught TypeError: foo is not a function                                                               
> 
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么以及何时被忽略的声明var foo = 2;生效,当立即执行产生时:

  foo
< undefined  
Run Code Online (Sandbox Code Playgroud)

我的理解是 JavaScript 引擎(预)编译解析步骤应该注意两个函数的声明,然后是变量的声明,按照这个顺序,然后,在执行步骤,foo();执行尝试应该像随后那样失败,如下:Uncaught TypeError: foo is not a function- 然而,这显然不是这种情况,因为foo将输出作为直接结果的一部分。