2011-09-15 83 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; 
    }; 
} 

这多半是一个兼容的垫片,它会为大多数情况下工作。