为什么不在关闭中重置变量(Javascript)

时间:2017-04-29 11:34:35

标签: javascript scope closures self-invoking-function

我一直在努力学习关闭,但有一件事仍困扰着我。如果我有以下代码:

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

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

// Returns "3"

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

3 个答案:

答案 0 :(得分:5)

  

如果我调用add()三次,为什么不每次都将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,每次都会创建一个新的计数器。

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

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