我有一段代码,我试图提醒[{1}}。我正确地使用关闭时遇到问题,所以我无法解决这个问题。
原始代码:
1,2,3
我正在尝试对function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[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]();
}
}
testList();
执行此类操作以使其正常工作:
buildList()
我知道我在使用闭包时犯了错误,我只是不确定问题是什么。
答案 0 :(得分:0)
您的第二次尝试更接近解决方案,但仍然无效,因为您最内层的功能是从顶级函数捕获变量item
:item
只是始终引用相同的实例,这是在致电buildList()
时创建的。
var
范围始终绑定到当前函数调用,而不是代码块,因此它不受for
等语句的控制。
因此,警报可能会显示调用'item' + (list.length-1)
时buildList()
的值。
由于您将i
传递给了闭包,因此您应该在该函数中声明var item
,例如:
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
result[i] = function(x) {
// x and item are both local variables of anonymous function declared just above
var item = 'item' + list[x]; // or maybe you meant 'item' + x?
return function() {alert(item + ' ' + list[x])};
}(i);
}
return result;
}
请注意,闭包仍会捕获对list
的引用,因此在buildList()
返回的数组中调用函数时将显示它包含的值。局部变量item
也是完全可选的,您可以调用alert('item' + x /*or is it list[x]?*/ + ' ' + list[x])
。
答案 1 :(得分:0)
来自How do JavaScript closures work?
请注意,当您运行示例时,&#34; item2 undefined&#34;警报三 倍!这是因为就像之前的例子一样,只有一个例子 buildList的局部变量的闭包。当匿名 函数在fnlistj行上调用;他们都使用相同的 单个闭包,它们使用i和item中的当前值 那一个闭包(我的值为3,因为循环有 已完成,且项目的值为&#39; item2&#39;)。请注意我们正在索引 0因此item的值为item2。而i ++将把我增加到 价值3。
如果要存储i
的匹配值,则需要在每次循环迭代中创建一个闭包:
function buildList(list) {
var result = [], item, closure;
for (var i = 0; i < list.length; i++) {
item = 'item' + list[i];
// call this function with the string you wish to store
// the inner function will keep a reference to the 'msg' parameter even after the parent function returns
closure = (function(msg) {
return function() {
alert(msg);
};
}(item + ' ' + list[i]));
result.push( closure );
}
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();