这对JavaScript函数有何不同?

时间:2016-06-29 06:27:23

标签: javascript lexical-closures

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

功能1



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




功能2



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




6 个答案:

答案 0 :(得分:3)

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

function (){
    return counter += 1;
}

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

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

答案 1 :(得分:2)

在案例1中,您将返回一个在外部 IIFE 上具有关闭的函数。因此,返回的函数即使在返回后也能够存储count的值(即Closure),因此每次调用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() {1}}

答案 2 :(得分: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());

注意add仅被调用一次,这意味着var counter = 0;只执行一次,plus是我们实际调用的函数。由于在plus中定义了add,因此可以访问counter

答案 3 :(得分:1)

您无法访问该机箱外部机箱内定义的任何变量。这可以帮助您避免冲突,例如,如果多个函数使用相同的变量名称。

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

以下是第一个片段中的确切情况。

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

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

需要注意的事项:

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

  2. 您可以通过在其后面放置()来执行机箱功能。

  3. 现在变量add是一个只增加counter的函数。这里环境设置为关闭 - 因此内部函数始终记住counter的先前值。

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