javascript:在函数(){}中使用当前的for循环计数器值?

时间:2010-08-10 10:58:03

标签: javascript scope copy for-loop anonymous-function

在网站上我想这样做:(简化)

myHandlers = new Array();
for(var i = 0; i < 7; i++) {
  myHandlers.push(new Handler({
    handlerName: 'myHandler'+i, // works, e.g. ->myHandler1, 2, 3 etc.
    handlerFunc: function(bla) { /*...*/ alert(i); } // doesn't work,all return 7
  }
}

我可以将计数器设置为我的处理程序的另一个属性(它会复制当前值)并在我的函数中使用它,但我想,还有一种实际复制此值的方法,不是吗?

3 个答案:

答案 0 :(得分:6)

当调用 handlerFunc 时,函数内的i引用i循环的for。但i可能不再具有相同的值。

使用闭包来绑定匿名函数范围内的i的当前值:

handlerFunc: (function(i) { return function(bla) { /*...*/ alert(i); }; })(i)

这里使用匿名函数(function(i) { … })(i)并立即调用。此函数将i循环的for值绑定到本地i。那么i独立于i循环的for

答案 1 :(得分:2)

var myHandlers = new Array();
for (var i = 0; i < 7; i++) {
  myHandlers.push(new Handler({
    handlerName: 'myHandler'+i, // works, e.g. ->myHandler1, 2, 3 etc.
    handlerFunc: 
    (function(i) { 
     return function(blah) { 
         alert(i) 
     }
     })(i)
  }))
}

使用闭包绑定i以使值保持不变

答案 2 :(得分:2)

在您的示例中,函数中的i与函数外的i变量相同。当i在循环中递增时,它在函数内递增。因此,如果在循环结束后调用这些函数,它们都将警告“7”。

您需要创建一个具有适当范围的新变量,并将i的值复制到其中。

这样的事情会产生预期的效果。

...
var pushHandler = function(i) {
  myHandlers.push(new Handler({
    handlerName: 'myHandler'+i, // works, e.g. ->myHandler1, 2, 3 etc.
    handlerFunc: function(bla) { /*...*/ alert(i); } // doesn't work,all return 7
  }
}
...
for(var i = 0; i < 7; i++) {
  pushHandler(i);
}

...