你引用的代碼不會做你所列出的東西,你可能失去了一些簡化它的問題。
此代碼將有你所描述的,雖然效果:
for(j in groups){
doSomething(function() {
// Callback for `doSomething`
console.log(j, somefunction(groups[j]));
});
}
需要注意的是,現在我創造一個功能(無論doSomething
不回調),而不僅僅是調用之一。
出現這種情況的原因是,所創建的功能具有持久參考到j
變量(和其中所有的執行上下文別的),而不是它的一個拷貝作爲創建功能時的感覺。它在該執行上下文中被稱爲關閉。所以你的循環運行,一系列調用doSomething
開始一系列的事情,然後在回調被調用時,j
是3,所以它們都是相同的。
通常的解決方法是創建一個可以關上的東西,他們被調用之前不會改變,這樣的功能:
for(j in groups){
doSomething(makeCallback(j));
}
function makeCallback(jarg) {
return function() {
console.log(jarg, somefunction(groups[jarg]));
};
}
現在,我們在我們的回調使用jarg
,而不是j
。由於jarg
是調用makeCallback
的上下文的一部分,因此它在創建函數和稍後調用它時不會發生變化。
您可以將數據綁定到功能的另一種方法是使用Function#bind
(其中有效在後臺創建一個封閉),這是在現有的NodeJS的ES5功能,因爲V8引擎,它。以下是如何將看:
for(j in groups){
doSomething(function(jarg) {
// Callback for `doSomething`
console.log(jarg, somefunction(groups[jarg]));
}.bind(this, j)); // <== Note the bind
}
以下容易混淆的(而且很有可能更有效):
for(j in groups){
doSomething(handler.bind(this, j));
}
function handler(jarg) {
// Callback for `doSomething`
console.log(jarg, somefunction(groups[jarg]));
}
更多有關閉:
有兩件事:1.您所引用的代碼沒有這樣做(您在簡化問題中丟失了一些東西 - 容易做到),2. JavaScript沒有任何引用形式的傳遞。所有參數都通過* value *傳遞。對象(包括函數)通過引用來引用,它與「通過引用傳遞」無關。 – 2012-07-24 15:40:12