如何从for循环中的匿名函数获取当前循环迭代?

时间:2011-09-15 15:55:21

标签: javascript loops for-loop iteration

  

可能重复:
  Javascript closure inside loops - simple practical example

我有一个带有匿名函数的for循环,在函数中我想访问当前的循环迭代。但由于某种原因而不是循环迭代,我得到4.唯一的另一个地方4是一个值是myArray.length。如果我将i作为参数传递,我会得到[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])
      });
   };
};

感谢。

2 个答案:

答案 0 :(得分: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);
    };
};

答案 1 :(得分: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;
    };
}

这是一个大多数兼容的垫片,适用于大多数情况。