Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 闭包中如何引用局部变量?_Javascript_Loops_Closures - Fatal编程技术网

Javascript 闭包中如何引用局部变量?

Javascript 闭包中如何引用局部变量?,javascript,loops,closures,Javascript,Loops,Closures,我正在读一篇文章(),其中一个例子如下 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() {

我正在读一篇文章(),其中一个例子如下

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();
函数构建列表(列表){
var结果=[];
对于(变量i=0;i
调用testList时,会出现一个警告框,显示“item3 undefined”。文章有这样的解释:

fnlist[j]()行调用匿名函数时它们都使用相同的单个闭包,并且它们使用该闭包中i和item的当前值(其中i的值为3,因为循环已完成,item的值为'item3')

为什么项的值为“item3”?当我变成3时,for循环不是结束了吗?如果结束,项目不应该仍然是“项目2”吗?或者,当testList调用函数时,是否再次创建变量项?

您已接近

为什么项的值为“item3”?当我变成3时,for循环不是结束了吗

如果它结束了,这个项目不应该仍然存在吗 “项目2”

没有。这个例子有点棘手。在循环的最后一次迭代中,
i
是2,但它引用了
list
数组的第三个元素,即3。换句话说,
item==“item”+列表[2]==“item3”

或者,当testList调用函数时,是否再次创建变量项


不,你第一次几乎是对的。我想您刚刚错过了
项[2]
的值为3。

循环在我变为3时结束,但存储在闭包中并通过警报显示的“item”变量设置为

var item = 'item' + list[i];

文本“item”+列表[2]中的值。第三个列表项是3,因此文本是item3

正如您所说,
list
变量存储在closure中


实际上,您可以访问
list
变量,但您正在尝试访问
list[3]
。毕竟,
i
变量也存储为闭包,当调用
console.log
函数时,它的值为3。

在执行以下操作之前,buildList中的for循环完成:

for (var j = 0; j < fnlist.length; j++) {
  fnlist[j]();
}

我想你遗漏的一点是,
list[I]
被低估了,因为
I
是3,而
list
只为0..2定义。

是不是一个bug导致了比预期链接更多的文本?哇,太简单了。我怎么会错过呢?从零开始计算总是把我搞得一团糟。谢谢如果这是您理解javascript闭包的唯一障碍,请拍拍自己的背!我认为这个例子太复杂了。@J-P,谢谢你的回复。我现在明白了为什么它是未定义的,但我可以问一下为什么你们的例子是有效的。为什么现在要为fnlist中存储的每个函数创建一个新的闭包?在“result.push”调用中声明和调用的函数会创建自己的闭包。@Pointy,为什么创建自己的闭包?因为它是一个匿名函数?@Nick,它创建自己的闭包仅仅是因为它是一个函数。函数中的函数形成闭包。。。因此,在循环的每次迭代中,我们都会创建一个新的闭包,它将保留
i
item
@J-P的当前值,谢谢你。我现在明白了。谢谢你的帮助。
function buildList(list) {
  var result = [];
  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push(
        (function(item, i){
            // Now we have our own "local" copies of `item` and `i`
            return function() {
                console.log(item + ' ' + list[i])
            };
        })(item, i)
    );
  }
  return result;
}