可能重复:
Javascript closure inside loops - simple practical example
我试图编写与此类似的代码:
var funcs = [];
for (var i=0; i<5 ; ++i) {
funcs[i]=function() {
alert(i);
};
}
显然,调用funcs[0]
不会按预期警告0
,只是因为匿名函数捕获了变量i
,并且调用任何funcs[0..4]
都会发出警报'4'(最后一次迭代后i
的值,并由所有创建的函数共享)。
我想到的第一个工作是使用某种函数发生器:
var funcs = [];
for (var i=0; i<5 ; ++i) {
funcs[i]=(function(cap) {
return function() {alert(cap)};
})(i);
}
这就是诀窍,但看起来真的令人费解并且难以阅读。没有使用函数包装器,有没有更好的方法来获得预期的行为?
答案 0 :(得分:2)
.bind
函数允许您将其他参数预绑定到绑定函数:
var funcs = [];
for (var i=0; i<5 ; ++i) {
funcs[i]=function(i) {
alert(i);
}.bind(this, i);
}
这是ES5功能,所以应该适用于IE9 +,Chrome,Safari,Firefox:
答案 1 :(得分:2)
你应该尽可能简单地写它。我觉得它很容易理解,但很难读懂。因此,简化它的一种方法是使用嵌套编码样式。我认为这不比现在简单得多。
我建议这样:
var funcs = [];
for (var i = 0; i < 5; ++i) {
funcs[i] = (
function (cap) {
return function () { alert(cap) };
}
)(i);
}
答案 2 :(得分:1)
恕我直言,出于性能和可读性的原因,命名函数通常都是优越的。为什么不这样做:
function foo (cap) {
return function () { alert(cap) };
}
var funcs = [];
for (var i=0; i<5 ; ++i) {
funcs[i]=foo(i);
}
答案 3 :(得分:0)
当您不想使用这些匿名函数嵌入代码时,解决方案是定义(命名)类嵌入状态(i)和函数(在原型中)。这更多是LOC,但有时更具可读性:
var funcs = [];
function MyFunc(i) {
this.i=i;
}
MyFunc.prototype.doIt = function(){
alert(this.i);
};
for (var i=0; i<5 ; ++i) {
funcs[i]=new MyFunc(i);
}
funcs[2].doIt();
答案 4 :(得分:0)
试试这个:
var funcs = [0, 1, 2, 3, 4].map(function(i) {
return function() {alert(i);};
});
注意:IE8及更早版本不支持map
,但它有common polyfill。