为什么在闭包环境中声明变量不起作用?

时间:2016-04-24 08:17:10

标签: javascript closures

根据我的理解,闭包创建了一个环境来链接函数外部的函数和参数,并允许函数内部的东西访问它们。

以下是带闭合的函数。当我执行此功能三次时。

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

我希望我得到1,因为每次执行add(),它都会将计数器重新声明为0并加1.这应该是 counter = 0,counter ++,counter = 0,counter ++,counter = 0 ,计数器++。但为什么它结果是 3

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

function myFunction(){
    document.getElementById("demo").innerHTML = add();
}

第二个问题是:

variable = (function() {})()

为什么我们添加一个额外的括号来包含该函数,以及为什么在该函数之后还有另外一个括号?

谢谢!

1 个答案:

答案 0 :(得分:3)

  

我希望我得到1,因为每次执行add(),它都会将计数器重新声明为0并添加1.

不,完全没有。 add指的是您从IIFE 返回的功能,即function () {return counter += 1;}。此功能不会将counter设置为0。

让我们记录add并查看它:

enter image description here

您现在看到调用add只会将1添加到counter,而不是其他内容吗?

如果提取函数,也许代码更容易理解。以下代码与您的结果完全相同:

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

// we are *calling* createAdd here, so `add` refers
// to the function defined in line 3 ( function () {return counter += 1;} )
var add = createAdd();

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

在这里,您可以看到createAdd(因此行var counter = 0)只执行一次,但createAdd中的返回的函数被执行多次

  

为什么我们添加一个额外的括号来包含该函数,以及为什么在该函数之后还有另外一个括号?

这称为立即调用的函数表达式(IIFE)。它定义了一个函数并立即执行它。这通常用于限制变量的范围(在本例中为counter)。

您可以认为(function() {}())等同于

function f() {}
(f())

IIFE只是将函数的声明和执行放在一个表达式中。这允许我们省略函数名称,以便我们不会污染范围。

相关问题:

  

为什么闭包环境中的变量声明不起作用?

我说它按预期正常工作。