考虑以下Javascript代码:
var a = [];
var f = function() {
for (var i = 0; i < 3; i++) {
a.push(function(){alert(i)});
}
for (var j = 0; j < 3; j++) {
a[j]();
}
};
警报三次打印出'3'。我想要一个不同的行为 - 在循环的每次迭代中生成一个打印i的当前值的函数。即3个打印不同索引的函数。
有什么想法吗?
答案 0 :(得分:7)
创建一个匿名函数,该函数接受i
作为参数并返回该特定函数:
for (var i = 0; i < 3; i++) {
a.push((function(i) {
return function() {
alert(i);
}
})(i));
}
for (var j = 0; j < 3; j++) {
a[j]();
}
或者做类似的事情:创建一个匿名函数,接受i
作为参数将函数添加到数组中:
for (var i = 0; i < 3; i++) {
(function(i) {
a.push(function() {
alert(i);
});
})(i);
}
for (var j = 0; j < 3; j++) {
a[j]();
}
答案 1 :(得分:6)
另一种方法,使用currying:
var a = [];
var f = function() {
for (var i = 0; i < 3; i++) {
a.push((function(a){alert(a);}).curry(i));
}
for (var j = 0; j < 3; j++) {
a[j]();
}
};
// curry implementation
Function.prototype.curry = function() {
var fn = this, args = Array.prototype.slice.call(arguments);
return function() {
return fn.apply(this, args.concat(
Array.prototype.slice.call(arguments)));
};
};
检查上面的代码段here。
答案 2 :(得分:1)
var iterate = (function () {
var i, j = [];
for (i = 0; i < 3; i += 1) {
j.push(i);
alert(j[j.length - 1]);
}
}());
您不需要关闭来仅输出值。但是,您的代码应包含在面向对象的包含的函数中。不必调用函数来执行。
答案 3 :(得分:0)
您可以将循环体放在匿名函数中:
var a = [];
for(var i = 0; i < 3; i++) (function(i) {
a.push(function() { alert(i); });
})(i)
for(var j = 0; j < 3; j++) {
a[j]();
}
通过创建该函数并将循环的值“i”作为参数传递,我们在循环体内创建一个新的“i”变量,它基本上隐藏了外部的“i”。你推入数组的闭包现在看到了新变量,当在第一个循环中调用外部函数函数时,该变量的值被设置。如果我们在创建新变量时使用不同的名称,这可能会更清楚......这也是同样的事情:
var a = [];
for(var i = 0; i < 3; i++) (function(iNew) {
a.push(function() { alert(iNew); });
})(i)
for(var j = 0; j < 3; j++) {
a[j]();
}
“iNew”的值分配为0,然后是1,然后是2,因为循环立即调用该函数。
答案 4 :(得分:-2)
功能(I){警报(I)