2013-06-29 65 views
1

当然,代码只会完成您的工作。setTimeout在“for循环”中无法正常工作

但我很困惑,为什么下面的代码:

var a = { 
    0: "Hi", 
    1: "Bye" 
} 

for (var b in a) { 
    setTimeout(function() { 
     console.log(b); 
    }, 1000); 
} 

而不是安慰 “0”,然后选择 “1”

我只是得到 “1” 的两倍。

我不知道为什么发生这种情况。我需要一个类似于我正在制作的脚本的设置,但我也遇到了同样的问题。

回答

4

这是因为你使用闭包是错误的。

在这种情况下,你使用的是封闭的可变bsetTimeout回调中,但直到回调执行,届时的更新为对象中的最后的值值的变量b的值没有抬起头来。

一个在这种情况下,解决方案是创建一个本地关闭下面给出

for (var b in a) { 
    (function(c){ 
     setTimeout(function() { 
      console.log(c); 
     }, 1000); 
    })(b) 
} 

演示:Fiddle

1

你可以这样来做太

for (var b in a) { 
    setTimeout(console.log.bind(console, b), 1000); 
} 

或者像这

for (var b in a) { 
    setTimeout(function(c) { 
     console.log(c) 
    }.bind(null, b), 1000); 
} 

也不像这个

// compatibility varies 
for (var b in a) { 
    setTimeout(function(c) { 
     console.log(c) 
    }, 1000, b); 
} 
+0

更多类似'的setTimeout(console.log.bind(控制台,B)' – Musa

+0

@Musa,'console.log.bind(NULL,B)'在这种情况下也可以。 'console.log'不需要自己的上下文来工作。 – naomik

+0

所以你没有得到'非法调用'? – Musa