JavaScript执行返回函数的函数

时间:2012-11-16 00:08:42

标签: javascript function scope

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

在第一个片段中,计数器函数被赋值给变量letsCount,它看起来像执行函数更新计数器函数中的var count。

但是在第二个片段中,直接执行该函数不会更新计数变量。

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

Snippet 1

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

Snippet 2

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

4 个答案:

答案 0 :(得分: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保留的值。

答案 1 :(得分:1)

Snippet 1 Snippet 2 的调用不同。您的第一个代码段引用了一个返回的函数,该函数保留在其范围内(是一个闭包,引用了count)。

你的第二个片段每次调用外部函数,总是返回对新函数的引用,并使用新的 count 的新闭包。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

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

// })();

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