javascript闭包立即评估[重复]
-
06-07-2019 - |
题
这个问题在这里已经有答案了:
- 循环内的 JavaScript 闭包 – 简单的实际示例 43 个答案
考虑以下 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 的当前值的函数。IE。3 个打印不同索引的函数。
有任何想法吗?
解决方案
创建一个接受的匿名函数 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]();
}
其他提示
另一种方法是使用 柯里化:
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)));
};
};
检查上面的代码片段正在运行 这里.
var iterate = (function () {
var i, j = [];
for (i = 0; i < 3; i += 1) {
j.push(i);
alert(j[j.length - 1]);
}
}());
您不需要闭包来仅仅输出一个值。但是,您的代码应该包含在面向对象的函数中。不必调用函数即可执行。
您可以将循环体放入匿名函数中:
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,因为该函数是由循环立即调用的。
函数(i){警报(i)
不隶属于 StackOverflow