3

我有以下两个计数器函数,它们在运行时返回不同的结果。

在第一个片段中,计数器函数被分配给变量letsCount,看起来执行该函数会更新计数器函数中的var count。

然而,在第二个片段中,直接执行该函数不会更新 count 变量。

您能否解释为什么它们有不同的结果以及将返回函数的函数分配给变量时会发生什么?

片段 1

function counter() {
    var count = 0;
    return function() {
        console.log(count++);
    }
}
var letsCount = counter();
letsCount();    // 0
letsCount();    // 1
letsCount();    // 2

片段 2

function counter() {
    var count = 0;
    return function() {
        console.log(count++);
    }
}
counter()();  // 0
counter()();  // 0
counter()();  // 0
4

4 回答 4

2

每次调用时,counter()您都会创建一个新的匿名函数实例,该实例具有自己的作用域变量。如果您想继续使用相同的功能,则必须执行以下操作:

var counter = (function () {
    var count = 0;

    var fn = function() {
        console.log(count++);
    };

    return function () {
        return fn;
    };
})();

counter()();  // 0
counter()();  // 1
counter()();  // 2

将创建一个匿名函数,然后将其存储在作用域fn函数中,然后我们返回一个函数,该函数在调用时将返回fn.

于 2012-11-16T00:10:51.480 回答
1

Snippet 1Snippet 2的调用不同。您的第一个片段有一个对返回函数的引用,并且该函数保留在其范围内(是一个闭包,具有对 的引用count)。

您的第二个代码段每次都调用外部函数,总是返回对新函数的引用,并带有一个新的新闭包count

于 2012-11-16T00:14:13.493 回答
0

在第一种情况下,您使用函数指针引用它。所以上下文被保存

而在第二种情况下,您正在调用该函数,其中计数为 0。所以变量在这里脱离了上下文,所以你看到的值为 0

于 2012-11-16T00:11:59.877 回答
0

实际上,为什么您会出现这种行为是完全有道理的。当您调用 时counter()(),将执行第一次counter()调用,有效地将变量重置count为 0。当您将变量设置为 时counter(),实际上是将其设置为返回的函数:

var letsCount = // (function() {
    // var count = 0;
    return function() {
        console.log(count++);
    }

// })();

然后当你调用时letsCount,你调用的是返回的函数而不是外部函数。

于 2012-11-20T16:40:01.373 回答