Foo
正如所料,以下代码由于未定义而引发错误:
window.Foo = Foo;
同样如预期的那样,这会引发相同的错误:
window.Foo = Foo;
Foo = function() {
...
};
奇怪的是,这很好用:
window.Foo = Foo;
function Foo(){
...
};
这怎么可能?JavaScript 不是逐行解释的吗?
Foo
正如所料,以下代码由于未定义而引发错误:
window.Foo = Foo;
同样如预期的那样,这会引发相同的错误:
window.Foo = Foo;
Foo = function() {
...
};
奇怪的是,这很好用:
window.Foo = Foo;
function Foo(){
...
};
这怎么可能?JavaScript 不是逐行解释的吗?
吊装只是这里故事的一部分。
首先,解释吊装:
当你var
在 JavaScript 程序中使用时,你声明了一个变量。无论该变量在 JS 作用域中的何处声明,它都会被提升到该作用域的顶部。JavaScript 只有 Global 或 Function 范围;在函数的情况下
function hoistAway() {
console.log(a);
var a = 5;
}
相当于
function hoistAway() {
var a;
console.log(a);
a = 5;
}
如您所见,声明被提升,但初始化没有。因此,此代码将登录undefined
控制台,而不是 5。但是,它会满足于a
存在。
当你不使用var
时,声明是不明确的,所以它不会被提升。因此:
function hoistAway() {
console.log(a);
a = 5;
}
将导致错误消息。
在您的示例中:
window.Foo = Foo;
Foo
从未声明过,所以你得到一个错误。
window.Foo = Foo;
Foo = function() {
...
};
同样, Foo 没有被声明,所以没有提升。作为记录:
window.Foo = Foo;
var Foo = function() {
...
};
不会抛出错误。但是,只有声明被提升,所以如果你做了类似的事情
var bob = {};
bob.Foo = Foo;
var Foo = function() {
...
};
那么bob.Foo
将是undefined
。的特殊情况window.Foo = Foo
很奇怪,因为Foo
和window.Foo
在全局范围内是相同的。
最后:
window.Foo = Foo;
function Foo(){
...
};
有效,因为函数声明(与函数表达式相反)也被提升了;名称和定义都被提升了,所以这将按预期工作。
首先解析脚本,允许您的代码调用稍后定义的函数。