2013-02-01 115 views
2

我有以下代碼:功能陣列和奇怪的行爲

var arr = [{Name: "foo", action: function(){ alert("foo")}}, 
     {Name: "bar", action: function(){ alert("bar")}} 
     ] 

var arr2 = {}; 

for(var i =0; i< arr.length; i++) 
{ 
    var bla = arr[i]; 
    arr2[bla.Name] = function(){ bla.action() }; 
}   

arr2.foo(); 
arr2.bar(); 

,提醒兩次「欄」。 當我反而做

arr2[bla.Name] = bla.action; 

工作。

任何方式,使其工作在第一種情況下(我需要追加在我的函數其他事情)

謝謝!

+0

修復它只是注意,'ARR2 = {}'實際上使'arr2'的對象。 –

+1

@AlvinWong:他*應該*在這裏使用一個對象。他有字符串鍵。 – mpen

+0

關閉。檢查此:http://stackoverflow.com/questions/111102/how-do-javascript-closures-work –

回答

3

這是因爲你的匿名函數中的bla是一個引用,並且它在循環內部不斷更新以指向下一個對象。當循環終止時,它們將全部指向循環內引用的最後一個元素。

你可以做這樣的事情

arr2[bla.Name] = (function(x) { return function(){ x.action(); }})(bla); 

fiddle

+0

太棒了,忘了那個!謝謝 – rbag

2

bla的值正在改變,您創建的函數將始終使用調用時的值。

您可以創建一個封閉保護bla變量:

for(var i =0; i< arr.length; i++) { 
    (function(bla){ 
     arr2[bla.Name] = function(){ bla.action() }; 
    })(arr[i]); 
}  

如果您action功能不需要任何上下文或參數,你也可以簡化環路

for(var i =0; i< arr.length; i++) { 
    var bla = arr[i]; 
    arr2[bla.Name] = bla.action; 
}