下面的第一个例子是来自John Resign的学习高级JavaScript http://ejohn.org/apps/learn/#62的#62。它被称为Fix the Broken Closures。例1失败了4次。示例2仅因为具有包装函数而不同,通过了4次。它是来自同一教程的示例#63
有人可以解释一下
1)为什么示例1中的i == count++
失败。
2)为什么i == count++
在包装函数的帮助下传递。包装器函数如何改变它以使其工作?
提前致谢。
示例1
var count = 0;
for ( var i = 0; i < 4; i++ ) {
setTimeout(function(){
assert( i == count++, "Check the value of i." );
}, i * 200);
}
示例2
var count = 0;
for ( var i = 0; i < 4; i++ ) (function(i){
setTimeout(function(){
assert( i == count++, "Check the value of i." );
}, i * 200);
})(i);
答案 0 :(得分:2)
这很简单。 由于setTimeout执行“异步”,因此循环继续运行时,无法在函数执行时告诉i的确切值。
通过使用函数包装器,有效地将调用主体视为函数,并且明确地传递i的值。
您可以通过将函数i param重命名为j或其他内容来清除这一点,并将函数的内部更新为从i到j
基本上它归结为范围
答案 1 :(得分:1)
i
在循环中递增,因此每次调用setTimeout
回调时,赔率都很高,i
的值将为4. i
的值保持其值,即使循环增加了周围的i
。function outerScope() {
var x = 2, y = 3;
function innerScope() {
var x = 3;
// Obviously this alerts 3.
alert(x);
// Since we have no 'y' defined, alert the value 3 from the outer scope.
alert(y);
}
// Introduce a new scope.
innerScope();
// Since we have left the inner scope x is now 2.
alert(x);
// Obviously this alerts 3.
alert(y);
}