JavaScript 函数闭包

  • JavaScript闭包

    JavaScript变量可以属于全局作用域或全局作用域。全局变量可以通过闭包实现本地(私有)。
  • 全局变量

    一个函数可以访问函数内定义的所有变量,如下所示:
    function myFunction() {
      var a = 4;
      return a * a;
    }
    尝试一下
    但是也可以访问函数外部定义的变量,如下所示:
    var a = 4;
    function myFunction() {
      return a * a;
    }
    尝试一下
    在最后一个示例中,a是全局变量。在网页中,全局变量属于window对象。页面中(和窗口中)的所有脚本都可以使用(和更改)全局变量。在第一个示例中,a是局部变量。局部变量只能在定义它的函数内使用。它隐藏在其他函数和其他脚本代码中。具有相同名称的全局变量和局部变量是不同的变量。修改一个,不修改另一个。
    在没有关键字var的情况下创建的变量始终是全局变量,即使它们是在函数内创建的。
    局部变量生命周期很短
    只要您的应用程序(您的窗口/您的网页)存在,全局变量就会存在。局部变量的寿命很短。它们在调用函数时创建,并在函数完成时删除。
    假设您想使用变量来计算某些内容,并且您希望此计数器可用于所有函数。您可以使用全局变量,并使用一个函数来增加计数器:
    // 初始化 counter
    var counter = 0;
    
    // 函数中 counter 递增
    function add() {
      counter += 1;
    }
    
    // 调用 add() 3  次
    add();
    add();
    add();
    
    // counter 现在应该是 3
    尝试一下
    上述解决方案存在问题:页面上的任何代码都可以更改计数器,而无需调用add()。计数器应该是add()函数的局部变量,以防止其他代码更改它:
    // 初始化 counter
    var counter = 0;
    
    // 增加计数器的函数
    function add() {
      var counter = 0; 
      counter += 1;
    }
    
    // 调用三次 add() 
    add();
    add();
    add();
    
    //计数器现在应该是3.但它是0
    尝试一下
    它没有用,因为我们显示全局计数器而不是本地计数器。我们可以通过让函数返回它来删除全局计数器并访问局部计数器:
    // 增加计数器的函数
    function add() {
      var counter = 0; 
      counter += 1;
      return counter;
    }
    
    // 调用三次 add() 
    add();
    add();
    add();
    
    //counter 现在应该是3.但它是1。
    尝试一下
    它没有用,因为我们每次调用函数时都会重置本地计数器。JavaScript内部函数可以解决这个问题。
  • JavaScript嵌套函数

    所有函数都可以访问全局范围。 实际上,在JavaScript中,所有函数都可以访问“上面”的范围。JavaScript支持嵌套函数。嵌套函数可以访问它们“上方”的范围。在此示例中,内部函数plus()可以访问counter父函数中的变量:
    function add() {
      var counter = 0;
      function plus() {counter += 1;}
      plus();    
      return counter; 
    }
    尝试一下
    如果我们能够从外部使用plus()这个函数,这可以解决反制困境。我们还需要找到一种counter = 0只执行一次的方法。我们需要闭包。
  • 闭包函数

    还记得自我调用的功能吗?这个函数有什么作用?
    var add = (function () {
      var counter = 0;
      return function () {counter += 1; return counter}
    })();
    
    add();
    add();
    add();
    
    //   counter 现在是 3
    尝试一下
    示例说明:
    为变量add分配自调用函数的返回值。自调用函数只运行一次。它将计数器设置为零(0),并返回一个函数表达式。这样添加成为一种功能。“精彩”部分是它可以访问父范围中的计数器。这称为JavaScript闭包。它使函数具有“ 私有 ”变量。计数器受匿名函数范围的保护,只能使用add函数进行更改。
    闭包是一个可以访问父作用域的函数,即使在父函数关闭之后也是如此。