【发布时间】:2018-11-28 03:31:55
【问题描述】:
就像之前在这里所说的:JavaScript closure inside loops – simple practical example
这段代码的输出总是3
var funcs = [];
for (var i = 0; i < 3; i++) { // let's create 3 functions
funcs[i] = function() { // and store them in funcs
console.log("My value: " + i); // each should log its value.
};
}
for (var j = 0; j < 3; j++) {
funcs[j](); // and now let's run each one to see
}
// My value: 3
// My value: 3
// My value: 3
发生这种情况是因为循环的匿名函数内部的全局i 和i 之间没有区别。这样当funcs[i] 被调用时,它的当前值已经是3。
解决这个问题的经典方法是通过闭包。
var funcs = [];
function createfunc(i) {
return function() { console.log("My value: " + i); };
}
for (var i = 0; i < 3; i++) {
funcs[i] = createfunc(i);
}
for (var j = 0; j < 3; j++) {
funcs[j](); // and now let's run each one to see
}
通过将函数创建包装在createfunc(i) 函数中,您可以确保“i”的值绑定到函数外部不变的值。
解决这个问题的一种方法是创建一个let 变量。
var funcs = [];
for (let i = 0; i < 3; i++) {
funcs[i] = function() {
console.log("My value: " + i);
};
}
funcs[0]();
funcs[1]();
funcs[2]();
funcs[3]();
通过这样做,我希望变量 let 在循环内仅可访问,因此在我调用函数时 i 仍然是 undefined。
由于它有效,看起来 JS 能够在仍在 for 循环中时分配正确的变量 i,并且在我调用函数时它分配了正确的值 i。
我错过了什么?
【问题讨论】:
-
顺便说一句,你的“闭包创造”可以是一个 IIFE。
funcs[i] = (function(i) {return function() {console.log(i);};})(i);- 显然有间距以提高可读性:D -
@NiettheDarkAbsol 是真的。不错。
标签: javascript closures