javascript函数关闭工作

时间:2014-02-06 09:26:49

标签: javascript closures

我正在阅读一本javascript书,并在闭包时遇到了以下代码

function constFunc() {
    var funcs = [];
    for (var i = 0; i < 10; i++) {
        funcs[i] = function () {
            return i;
        }
    }
    return funcs;
}
var f = constFunc();
f[5]();

输出不是5。 给出的解释是&#34;嵌套函数不会制作范围的私有副本&#34;。 如果有人能解释上述声明,我将不胜感激。

4 个答案:

答案 0 :(得分:2)

当你调用constFunc时,循环运行并为funcs数组的每个元素分配一个函数。这些函数都返回i的值,该值在循环的每次迭代中从0更改为9

这意味着,constFunc执行i后,9的值将为i。当你调用数组中的一个函数时,它会返回9的值,正如我们刚刚看到的那样i。在循环的每次迭代中都没有捕获for (var i = 0; i < 10; i++) { (function (i) { funcs[i] = function () { return i; }; }(i)); } 的值。

你可以通过循环中的闭包来强制它被捕获:

i

在这种情况下,您将在循环的每次迭代中有效地创建一个与i具有相同值的新变量。您可以在行动中看到here

通过将i传递给函数,您最终会复制它的值。因此,在第一次迭代0上的值为i。我们将该值传递给新函数(参数i是与循环初始化器中声明的i不同的变量),然后从数组函数返回该值。这样,每个数组函数都返回不同的 i,而不是每个都返回相同的{{1}}。

答案 1 :(得分:2)

你为什么期望5的输出?因为在创建函数时,i是5.现在,正如我们所看到的,输出不是5(但是,如果我没有错过任何内容,9)。那为什么呢?

创建函数时,不会评估闭包内的i,但是当它运行时。现在,这就是你发表的声明发挥作用的地方:只有一个i - 在constFunc内创建的声明。所有关闭都适用于那个。在constFunc si完成工作之后,我显然具有9的值(因为这是循环停止的地方)。所有闭包现在输出9。

一个更简单的例子:

function outer () {
    var i = 0;
    function inner () {
        return i;
    }
    i = 99;
}

outer();
inner(); // <- return 99, not 0.

答案 2 :(得分:1)

这个循环:

for(var i=0;i<10;i++)
{
    funcs[i]=function(){return i;}
}

由于关闭,内部函数你正在访问i的父级变量,完成循环之后将是10.因此在循环后调用这些函数时它将返回你的值为10的值。

您可以通过将变量作为参数传递来解决它,因为参数创建了变量的新副本,即使在循环完成时也保持其状态。

var myFunctions= [];

function createMyFunction(i) {
    return function() { 
           console.log("My value: " + i); 
    };
}

for (var i = 0; i < 3; i++) {
    myFunctions[i] = createMyFunction(i);
}

答案 3 :(得分:1)

有一个名为i的变量。

有10个函数返回i

这些函数中的每一个都返回单个i变量的当前值。