2012-03-15 82 views
-1
this.config = { 
    source: psource, 
    _events: [ 
     'value1', 
     'value2', 
     'value3' 
    ] 
}; 

// Add callbacks to source 
var that = this; 
for (var i = this.config._events.length - 1; i >= 0; i--) { 
    var name = this.config._events[i]; 
    console.log(name); // correct 

    $(this.config.source).on(name, function() { 
     console.log(name); // value1 
     console.log(that.config._events[i]); // undefined 
    }); 
} 

我看不出這裏有什麼問題。我刪除了所有複雜的版本,並放入最簡單的版本,它根本不想工作。第一個console.log正確輸出所有正確的名稱,但它的行爲像循環一次發生,然後再次爲內部console.log的。閉環影響循環中閉合函數中的變量

任何人都可以看到有什麼問題嗎?

+0

聲明「閉包正在影響所有事情,而不僅僅是這一點」並未描述問題 - 閉包如何工作。封閉範圍中的所有變量都包含在閉包中。 – nrabinowitz 2012-03-15 18:25:41

+0

請使用更具描述性的內容修改問題的標題。我認爲你應該提到術語'for循環' – viebel 2012-03-15 18:37:04

+0

重複http://stackoverflow.com/questions/2192348/closures-in-a-for-loop – viebel 2012-03-16 10:56:56

回答

2

在該塊

console.log(that.config._events[i]); // undefined

i將結束是-1每次你關閉被調用時。

你將不得不做類似的東西,以創造一個封閉周圍i

$(this.config.source).on(name, function(i) { return function() { 
     console.log(name); // value1 
     console.log(that.config._events[i]); // undefined 
    }; 
}(i)); 
+0

更好的是,將'i'作爲參數傳遞給''。 on'方法,並使用'event.i'訪問變量。有關我的建議的更多詳細信息,請參閱'.on()'的文檔:http://api.jquery.com/on/ – 2012-03-15 18:26:53

+0

@RobW這可能適用於這種情況,因爲我是數字基元。然而,我故意選擇了這個解決方案,以便操作員能夠理解,在閉包中保持對變量的引用並不等於在閉包創建時保持對它的當前值的引用。 – Damp 2012-03-15 18:31:51

-1

在Javascript中,不建議定義for循環中的功能。

相反,您應該使用一個JavaScript庫,例如提供each例如underscore。然後你的代碼將如下所示:

_.each(this.config._events, function(e) { 
     $(this.config.source).on(name, function() { 
      console.log(e); 
     }); 

您可能想要先顛倒數組。

這裏是doc for _.each

你也可以使用jQuery的$.each它提供了一個類似的界面。

+1

-1在'for'循環中定義一個函數是完全安全的。你只需要注意變量的範圍以及閉包的工作方式。 – Damp 2012-03-15 18:38:02

+1

我用'危險'取代'不安全'。這導致了很多混亂。實際上,'jslint'不允許。請投回 – viebel 2012-03-15 18:40:35

+1

也沒什麼危險的。它的工作原理應該如此。我支持我的-1。 'jslint'不允許它是他們的選擇,而不是javascript問題。 – Damp 2012-03-15 18:44:22