2016-03-07 89 views
0

我在函數內部循環的變量:循環中的變量 - 如何修復它在我的情況?

function myHandler() { 
    for (var i = 0; i < items.length; i++) { 
    var currItem = items[i]; 

    myObj.doSomething(function(data) { 
     console.log("ok"); 
     console.log("My currItem id: " + currItem.id); // the last one of all in items 
    }, function(e) { 
     console.log("error"); 
     console.log("My currItem id: " + currItem.id); // the last one of all in items 
    }); 
} 

currItem.id每次中的console.log()是等於最後在項中的項的。明顯。我試圖解決這個問題:

function myHandler() { 
    for (var i = 0; i < items.length; i++) { 
    var currItem = items[i]; 
    var currItem = (function(i2) { 
     return items[i2]; 
    })(i); 

    myObj.doSomething(function(data) { 
     console.log("ok"); 
     console.log("My currItem id: " + currItem.id); // the last one of all in items 
    }, function(e) { 
     console.log("error"); 
     console.log("My currItem id: " + currItem.id); // the last one of all in items 
    }); 
} 

而且仍然沒有成功。爲什麼以及如何解決它?

+0

@elclanrs,沒有.. – Mario

+0

@Mario:錯誤的;這正是你的問題。通過調用一個函數來填充一個變量並不會改變捕獲該變量的方式。 – SLaks

+0

是啊,看起來你沒有正確地應用修復...更容易使用'forEach' – elclanrs

回答

1

使用封這樣的:這是被送回會記住其所創建的環境

內部函數。

function myHandler() { 
    for (var i = 0; i < items.length; i++) { 
    var currItem = items[i]; 

    myObj.doSomething((function(currItem) { 
     return function(data) { 
     console.log("ok"); 
     console.log("My currItem id: " + currItem.id); 
     } 
    })(currItem), (function(currItem) { 
     return function(e) { 
     console.log("error"); 
     console.log("My currItem id: " + currItem.id); 
     } 
    })(currItem)); 
    } 
} 

或者:

使用[].forEach,因爲每個迭代器回調都會有它自己的上下文,不會被下一次迭代被覆蓋..

0

如果doSomething方法是異步,這意味着回調在for循環之後運行,那麼currItem將永遠是最後一個。

原因是閉包,回調函數有一個閉包,它包含所有需要的函數執行信息,包括對變量currItem的引用。

因爲它是一個引用,所以當循環結束時,currItem的值是最後一項,然後才調用回調函數。

解決它的最簡單方法是將for循環的內部調用移動到一個將接受變量currItem作爲參數的函數。這樣變量不會改變。

可以使用數組的forEach功能,像這樣做:

items.forEach(function(currItem){ 
.... 
});