问题是关闭工作

时间:2016-04-22 15:11:10

标签: javascript closures

我有一段代码,我试图提醒[{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()

我知道我在使用闭包时犯了错误,我只是不确定问题是什么。

2 个答案:

答案 0 :(得分:0)

您的第二次尝试更接近解决方案,但仍然无效,因为您最内层的功能是从顶级函数捕获变量itemitem只是始终引用相同的实例,这是在致电buildList()时创建的。

JavaScript中的

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();

同样的问题herehere。相同的答案herehereherehere,可能还有十几个地方。