【发布时间】:2019-12-28 16:30:50
【问题描述】:
在关注 Kyle Simpson 在Pluralsight 上的 Advanced JavaScript 时,我遇到了这段代码,它应该证明函数声明在之前变量声明:
foo();
var foo = 2;
function foo() { console.log("bar"); }
function foo() { console.log("foo"); }
(请注意,上面的代码要么输入为带空格而不是换行符的单行,要么在输入整个代码之前使用SHIFT+ENTER防止立即执行。)输入整个的立即结果 上面在 Node 或 (Chrome) 控制台中的代码(并按 Enter 键)是:
foo
< undefined
套用 Kyle 的解释,第一个 function foo 声明被第二个覆盖,所以 foo 输出到控制台,并且由于 foo 已经声明为函数,var foo 声明被 (预)编译器。
直接的结果支持了被忽略的理论,然而,随后对foo 和foo() 的调查显示了一个不同的故事:
> foo
2
> foo()
Uncaught TypeError: foo is not a function
>
有人能解释一下为什么以及什么时候var foo = 2; 的被忽略声明在立即执行时产生:
foo
< undefined
我的理解是,JavaScript 引擎(预)编译解析步骤应该注意两个函数的声明,然后是变量的声明,按顺序,然后,在执行步骤,foo(); 执行尝试应该失败,因为随后它会使用:Uncaught TypeError: foo is not a function - 但显然情况并非如此,因为foo 将输出作为即时结果的一部分。
【问题讨论】:
-
我不清楚你为什么认为这与解释有冲突。
-
您何时输入
foo并获得undefined?控制台不是检查提升的好地方,因为它无法在你输入之前知道你要输入什么,但提升依赖于 JavaScript 引擎预先扫描整个范围。 -
@jonrsharpe 没有立即结果的冲突,正如凯尔所解释的那样。然而,随后对 foo 和 foo() 的调查,实际上并没有被 Kyle 讨论,这只是我的“好奇/勤奋:)”表明最终会发生其他事情,这导致随后的结果与结果相矛盾立即执行。
-
@jonrsharpe - 继续:立即执行:1) foo 是一个函数,因此被执行,2) var foo 声明被忽略。随后的结果: foo 是一个(非函数)2 号引用变量 - 所以它显然以某种方式被声明和分配(不被忽略) - foo() 因此突然抛出异常。这是 JavaScript 语言规范预期的行为,还是一个错误? V8发动机规格如何?有人知道吗?
-
"由于
foo已被声明为函数,var foo声明被(预)编译器忽略" - 仅指var关键字,这意味着它不会再次单独声明(或抛出关于重新声明变量的错误,就像let会)。但是在执行代码时,foo = 2初始化仍然像赋值一样运行。
标签: javascript