考虑这样的循环:
for(var it = 0; it < 2; it++)
{
setTimeout(function() {
alert(it);
}, 1);
}
输出结果为:
=> 2
=> 2
我希望它是:0,1。我看到两种解决方法:
解决方案#1。
这个基于我们可以将数据传递给setTimeout的事实。
for(var it = 0; it < 2; it++)
{
setTimeout(function(data) {
alert(data);
}, 1, it);
}
解决方案#2。
function foo(data)
{
setTimeout(function() {
alert(data);
}, 1);
}
for(var it = 0; it < 2; it++)
{
foo(it);
}
还有其他选择吗?
答案 0 :(得分:43)
除了你提出的两种方式之外,其实并不多,但这是另一种
for(var it = 0; it < 2; it++)
{
(function() {
var m = it;
setTimeout(function() {
alert(m);
}, 1);
})();
}
基本上,您需要在闭包中捕获变量值。此方法使用立即调用的匿名函数捕获局部变量it
中的外部变量值m
。
这是一个 Working Demo 。将 / edit 添加到网址以查看代码
答案 1 :(得分:14)
使用let关键字,您可以完全解决这个问题:
for(let it = 0; it < 2; it++)
{
setTimeout(function() {
alert(it);
}, 1);
}
答案 2 :(得分:1)
与上述解决方案类似,但在setTimeout函数内部自行调用
for(var it = 0; it < 2; it++)
{
setTimeout(function(cur) {
return function(){
alert(cur);
};
}(it), 1);
}
答案 3 :(得分:1)
与其他解决方案类似,但在我看来更干净:
for (var it = 0; it < 2; it++) {
// Capture the value of "it" for closure use
(function(it) {
setTimeout(function() {
alert(it);
}, 1);
// End variable captured code
})(it)
}
这为捕获保留了相同的变量名称,并为整个循环执行此操作,将其与超时设置的逻辑分开。如果你想在块中添加更多逻辑,你可以轻而易举地做到这一点。
我唯一不喜欢解决方案的是最后重复“它”。