闭包规则是:函数使用定义时有效的作用域链执行。
在下面的 setTimeout 回调函数中,x 在定义时尚未在范围内。因此,程序应该打印未定义,但它打印 7,为什么?我错过了什么?
var foo = function () {
setTimeout(function (){
console.log(x);
}, 3000);
};
var x = 7;
foo();
还是因为上面的代码和下面的代码完全一样?
var x = 7;
var foo = function () {
setTimeout(function (){
console.log(x);
}, 3000);
};
foo();
x 在定义时尚未在范围内
这不是真的。 原因是吊装。 基本上,JavaScript 会将任何var
或命名function
移动到包含范围的顶部。 所以你实际拥有的更像是这样的东西:
// these variables are hoisted
var x;
var foo;
// then the variables are assigned.
foo = function () {
setTimeout(function (){
console.log(x);
}, 3000);
};
x = 7;
foo();
在此处阅读有关吊装的更多信息。
此外,这是准确的:
函数使用定义函数时有效的作用域链执行。
但是你的解释并不准确。 他们有权访问定义它们的范围,但不能在定义它们时访问。 变量可以具有随时间变化的值,在这些作用域中声明的函数将使用该作用域中的最新值。 没有时间机器。
因此,当嵌套函数执行时,foo
7
,因为在该范围内,在那一刻,foo
确实是7
。