2011-09-15 84 views
1

可能重複:
Javascript closure inside loops - simple practical example如何從for循環中的匿名函數獲取當前循環迭代?

我有一個與內部的匿名函數循環,並且在功能我想訪問本次循環。但由於某種原因而不是循環迭代,我得到了4.唯一的其他地方4是一個值是myArray.length。如果我通過我作爲參數,我得到[object Object]。我究竟做錯了什麼?我的代碼:

var width = function(){ 
    for(var i = 0, len = myArray.length; i < len; ++i){ 
     alert(i) //this outputs the current iteration 
     myArray[i].load(function(){ 
     alert(i) //this outputs 4 (or [object Object]) 
     }); 
    }; 
}; 

感謝。

回答

4

傳遞給.load的匿名函數在循環完成後正在執行。

你必須創建一個本地範圍,並複製i變量:

var width = function(){ 
    for(var i = 0, len = myArray.length; i < len; ++i){ 
     (function(i){ 
      myArray[i].load(function(){ 
       alert(i) //this outputs 4 (or [object Object]) 
      }); 
     })(i); 
    }; 
}; 
0

ECMAScript 5包括bind()[docs],這是用來獲取綁定到它與this值的函數以及參數值。

function loader(i){ 
    alert(i); 
} 

var width = function(){ 
    for(var i = 0, len = myArray.length; i < len; ++i){ 
     alert(i); 
     myArray[i].load(loader.bind(null, i) ); 
    } 
}; 

在這裏,我結合null作爲函數的this返回值,但可以將其設置爲別的東西。然後我將當前值i作爲第一個參數。


要獲得支援舊版瀏覽器(如果需要),包括墊片from MDN

if (!Function.prototype.bind) { 
    Function.prototype.bind = function (oThis) { 
     if (typeof this !== "function") // closest thing possible to the ECMAScript 5 internal IsCallable function 
     throw new TypeError("Function.prototype.bind - what is trying to be fBound is not callable"); 
     var aArgs = Array.prototype.slice.call(arguments, 1), 
      fToBind = this, 
      fNOP = function() {}, 
      fBound = function() { 
       return fToBind.apply(this instanceof fNOP ? this : oThis || window, aArgs.concat(Array.prototype.slice.call(arguments))); 
      }; 
     fNOP.prototype = this.prototype; 
     fBound.prototype = new fNOP(); 
     return fBound; 
    }; 
} 

這多半是一個兼容的墊片,它會爲大多數情況下工作。