如何在列表函数中修复此闭包?
How can I fix this closure within a list function?
这个 very good Stack Overflow answer 给出了一个例子,说明当 return 在列表中使用匿名函数时闭包如何反直觉地工作。
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + i;
result.push( function() {alert(item + ' ' + list[i])} );
}
return result;
}
function testList() {
var fnlist = buildList([1,2,3]);
// Using j only to help prevent confusion -- could use i.
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}
此代码将 return:
item2 undefined
item2 undefined
item2 undefined
我的问题是 - 您将如何修改此代码以使其 return 成为我们期望的结果?
item0 1
item1 2
item2 3
在 buildList
的 for
循环中使用 IIFE 并传入 i
.
这将确保传入的 i
将保持包含在 IIFE
闭包中,并且不会被 for
循环中的 i
更改
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
//the IIFE
(function(i) {
var item = 'item' + i;
result.push(function() {
console.log(item + ' ' + list[i])
});
})(i);
}
return result;
}
function testList() {
var fnlist = buildList([1, 2, 3]);
// Using j only to help prevent confusion -- could use i.
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}
testList();
这个 very good Stack Overflow answer 给出了一个例子,说明当 return 在列表中使用匿名函数时闭包如何反直觉地工作。
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + i;
result.push( function() {alert(item + ' ' + list[i])} );
}
return result;
}
function testList() {
var fnlist = buildList([1,2,3]);
// Using j only to help prevent confusion -- could use i.
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}
此代码将 return:
item2 undefined
item2 undefined
item2 undefined
我的问题是 - 您将如何修改此代码以使其 return 成为我们期望的结果?
item0 1
item1 2
item2 3
在 buildList
的 for
循环中使用 IIFE 并传入 i
.
这将确保传入的 i
将保持包含在 IIFE
闭包中,并且不会被 for
循环中的 i
更改
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
//the IIFE
(function(i) {
var item = 'item' + i;
result.push(function() {
console.log(item + ' ' + list[i])
});
})(i);
}
return result;
}
function testList() {
var fnlist = buildList([1, 2, 3]);
// Using j only to help prevent confusion -- could use i.
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}
testList();