【问题标题】:How to get current loop iteration from anonymous function within the for loop? [duplicate]如何从 for 循环中的匿名函数获取当前循环迭代? [复制]
【发布时间】:2011-11-18 00:41:50
【问题描述】:

可能重复:
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])
      });
   };
};

谢谢。

【问题讨论】:

    标签: javascript loops for-loop iteration


    【解决方案1】:

    你传递给.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);
        };
    };
    

    【讨论】:

      【解决方案2】:

      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 的当前值绑定为第一个参数。


      要获得对旧版浏览器的支持(如果需要),请添加 shim 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;
          };
      }
      

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

      【讨论】:

        猜你喜欢
        • 2013-05-23
        • 1970-01-01
        • 2011-08-05
        • 2014-09-12
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 2015-06-13
        相关资源
        最近更新 更多