2

我一直在尝试了解闭包,但有一件事仍然让我感到困惑。如果我有以下代码:

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();

add();
add();
add();

// Returns "3"

如果我调用 add() 三次,为什么不每次都将 counter 设置为零,然后返回将 counter 加一的匿名函数?一旦自调用函数运行,它会跳过它吗?对不起,如果这个问题看起来很简单,我很难理解它。任何帮助将不胜感激。

4

3 回答 3

6

如果我调用 add() 三次,为什么不每次都将 counter 设置为零,然后返回将 counter 加一的匿名函数?

因为add 那个匿名函数,因为包含的函数counter调用并且它的结果被分配给add

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();
//^^----------- calls the outer function, returns the anonymous inner function

如果你没有调用它:

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
});
//^--- no () here

...然后add会按照你说的做,每次你调用它时,它都会返回一个带有自己计数器的新函数:

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
});

var a = add();
var b = add();
var c = add();

console.log("a's first call:  " + a());
console.log("a's second call: " + a());
console.log("a's third call:  " + a());
console.log("b's first call:  " + b());
console.log("b's second call: " + b());
console.log("b's third call:  " + b());

console.log("a's fourth call: " + a());
console.log("b's fourth call: " + b());
.as-console-wrapper {
  max-height: 100% !important;
}

那不是重置 counter,而是每次都创建一个新计数器。

于 2017-04-29T11:38:06.273 回答
2

通过调用add(),您实际上并不是在执行外部函数,而是在执行内部函数。对于内部函数,counter 就像一个全局变量,被设置一次0后就再也没有设置为0。在调用add()时,您正在执行内部函数内的行,从而增加计数器。

于 2017-04-29T11:41:54.117 回答
2

分配给的值add是 IIFE 的结果,其中创建了闭包。也许更明显的是当add()被调用时会发生什么,当它的创建被写成如下(相当于你的原始代码):

var add;
(function () {
    var counter = 0;
    add = function () {return counter += 1;};
})();
于 2017-04-29T12:34:17.620 回答