2013-06-29 66 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