2013-07-11 70 views
3

我嘗試在循環中創建具有函數的數組。但我認爲沒有關於封裝的東西。向循環中的javascript數組添加函數

例如,此代碼返回「y y」。 Live demo

HTML

<div id="result"></div> 

的Javascript

var json = { 
      '1':'x', 
      '2':'y' 
      }; 
var my_array = []; 
var div = document.getElementById('result'); 

for (var key in json) { 
    my_array.push(function() { 
     div.innerHTML = div.innerHTML + ' ' + json[key]; 
    }); 
}; 

var length = my_array.length; 

for (var i = 0; i < length; i++) { 
    my_function = my_array[i]; 
    my_function(); 
} 

我應該怎麼做才能 「x和y」?

Tnx很多。

+0

另一種情況,通過關閉 – NicoSantangelo

+0

咬它不起作用,因爲當你ü你調用該函數的關鍵變量的值是'2' –

+0

@KamenStoykov,哦,我知道它爲什麼不起作用:) – Yevgen

回答

8

這是由於閉包在JavaScript中的工作方式。

你想是這樣的:

for (var key in json) { 
    (function(key) { 
     my_array.push(function() { 
      div.innerHTML = div.innerHTML + ' ' + json[key]; 
     }); 
    })(key); 
} 

在JavaScript中,閉包或匿名函數是詞法綁定到它們所定義的範圍。這意味着他們可以訪問已定義的範圍中定義的所有變量,其中關閉是定義的。

所以在你的原始代碼中,你有key,最初指向1。在您的功能中,您有​​,最初爲json[1],即x。然後當循環進行到下一次迭代時,您將key設置爲2。但事情是key在第一個功能實例和第二個功能實例都指向相同的位置。所以當你最終評估這個函數時,他們會在執行時使用任何值key。在執行時,key設置爲2,因爲這是循環結束時的最後一個值key

要解決這個問題,您必須通過使用匿名自調用函數來引入新範圍。通過使用這種模式,您有意引入一個新的範圍,使得該新範圍中的key有其自己的位置,並且與外部範圍中的key不同。

Check out the updated fiddle

+0

這不起作用......即使您可以確定問題,您也可能希望在將其作爲答案提交之前驗證您的代碼是否正常工作 – taylorc93

+1

@ taylorc93小寫字母;固定。 –

+0

您不必「**必須**通過使用匿名自調用函數來引入新範圍」。你可以通過調用一個傳遞必要事物並返回一個新函數/作用域的函數以更清晰的方式來完成它。 – Ian