3

我很难辨别 JavaScript 闭包是如何工作的。请看一下这两个函数,并说明它们在多次调用时产生完全不同的结果的不同之处:

功能一

var add = (function() {
  var counter = 0;
  return function() {
    return counter += 1;
  }
})();
console.log(add()); // result is 1
console.log(add()); // result is 2
console.log(add()); // result is 3

功能二

function add() {
  var counter = 0;
  function() {
    return counter += 1;
  }
  plus();
}
console.log(add()); // result is 1
console.log(add()); // result is 1
console.log(add()); // result is 1

4

6 回答 6

3

在第一个示例中,声明了 counter 并且调用时调用的函数add本质上是:

function (){
    return counter += 1;
}

这很重要,因为counter不会在每次add调用时都重新声明。

在第二个示例中,counter每次add调用时都会重新声明。

于 2016-06-29T06:35:34.367 回答
2

在情况 1 中,您返回的函数在外部IIFE上有一个闭包。因此,即使在返回(即闭包)之后,返回的函数也能够存储 count 的值,因此每次调用时都会获得更新的值add()

您的案例 2 似乎不正确。你没有plus定义函数。即使你定义了它,你也会得到undefined,因为你没有返回任何东西add()

function add() {
  var counter = 0;
  function plus () {
    return counter += 1;
  }
  plus();
}
console.log(add()); // result is 1
console.log(add()); // result is 1
console.log(add()); // result is 1

当你plus()从它返回时,你只会得到1,因为你实际上是在counter += 1每次counter is reset to 0调用时返回执行的结果add()

于 2016-06-29T06:35:06.823 回答
2

这对 JavaScript 函数有何不同?

在每个示例中,您都声明了两个函数,一个嵌套在另一个函数中。

在第一个示例中,您调用外部函数一次,返回内部函数并将其分配给add。这意味着调用add只会执行内部函数

在第二个例子中,add指的是外部函数。因此调用add将始终执行外部和内部函数。


如果我们稍微重写第一个示例,您可能会更好地看到差异(它仍然产生相同的结果):

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

var plus = add();
console.log(plus());
console.log(plus());

注意how addis only called once,这意味着var counter = 0;它只执行一次,并且plus是我们实际调用的函数。因为plus是在里面定义的add,所以可以访问counter

于 2016-06-29T06:40:43.907 回答
1

您不能访问在该外壳之外的外壳内定义的任何变量。这可以帮助您避免冲突,例如多个函数使用相同的变量名。

于 2016-06-29T06:31:35.650 回答
0

这是第一个片段中发生的确切情况。

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

在上面的语句中,您为变量分配了add一个增加counter.

注意事项:

  1. 您可以通过执行附件功能来获得此功能。(请注意附件函数返回的内容)

  2. 您可以通过将其放在后面来执行封闭功能()

现在变量add是一个函数,它只会增加counter. 这里环境被设置成闭包——所以内部函数总是记住counter.

因此,每次通过add变量执行内部函数时,您都会看到增加的数字。

于 2016-06-29T06:46:35.440 回答
0

在第一个示例中,外部函数运行一次,它将计数器变量设置为零。外部函数返回内部函数,并将其分配给变量add。当您调用add()时,内部函数在它声明的上下文中运行,因此它可以递增计数器变量。

在第二个示例中,声明了外部函数,名称为add。每次调用时都运行这个外部函数add。这个外部函数每次都将计数器设置为零,然后运行内部plus函数,它将计数器递增到 1 并返回它。

于 2016-06-29T06:41:08.167 回答