【问题标题】:javascript closure in loop循环中的javascript闭包
【发布时间】:2014-08-17 19:08:54
【问题描述】:

给出以下代码:

var a = [ ], i = 0, j = 0;

for (i = 0; i < 5; i += 1) { 

  (function(c) {
    a.push(function () { 

    console.log(c); });

  })(i);
};

for (j = 0; j < 5; j += 1) { a[j](); } 

为什么i 总是变大1 而不是保持5?是不是已经通过了for循环,所以给匿名函数的i参数应该是5

【问题讨论】:

  • 因为你在每次迭代中创建一个新的范围,通过调用一个函数来捕获i的当前值。

标签: javascript for-loop closures


【解决方案1】:

如果您从内部闭包中引用了i,那么是的,您会看到所有情况下的结果都是 5。但是,您将i 按值 传递给外部函数,它被接受为参数c。然后将c 的值固定为i 在您创建内部闭包时的任何值。

考虑更改日志语句:

console.log("c:" + c + " i:" + i);

您应该看到c 从 0 变为 4(含),i 在所有情况下都为 5。

【讨论】:

  • 感谢您的回答,所以我基本上为每个循环创建了一个内部闭包,它可以访问自己的 i 值?
  • @AndyB 有点像,从技术上讲,您创建内部闭包,每个闭包都有自己的 c 变量,每个变量都初始化为创建闭包时 i 持有的值。
【解决方案2】:

chhowie 的回答绝对正确(我赞成),但我想再向您展示一件事以帮助理解它。您的内部函数的工作方式类似于更明确的函数调用,如下所示:

var a = [ ], i = 0, j = 0;

function pushFunc(array, c) {
    array.push(function () { 
        console.log(c); 
    });
}

for (i = 0; i < 5; i += 1) { 
    pushFunc(array, i);
}

for (j = 0; j < 5; j += 1) { a[j](); } 

这也应该可以帮助您了解c 是如何来自函数参数,而不是来自for 循环。您的内部函数与此完全相同,只是没有外部声明的命名函数。

【讨论】:

    猜你喜欢
    • 2018-06-10
    • 1970-01-01
    • 2014-10-10
    • 2011-01-12
    • 1970-01-01
    • 2014-01-15
    • 2017-02-19
    • 2017-02-14
    • 1970-01-01
    相关资源
    最近更新 更多