基本概念

函数和声明该函数的词法环境的组合。闭包包含了函数也包含了声明该函数的词法环境(作用域)。

闭包实际上是将函数与其所操作的某些数据(环境)关联起来,这些数据或者是环境可以理解为它的一个作用域。因此我们可以达到一个能够访问另一个函数作用域的变量的函数的目的。

//定义局部变量
function count() {
    let count = 0;
    return function() {
        count = count + 1;
        console.log(count);
    }
}

var getCount = count();

getCount();
getCount();
// 1
// 2

特点

闭包一定return一个function,只有function才会有一个封闭的命名空间。

  • 函数嵌套函数
  • 函数内部可以引用外部的参数和变量
  • 参数和变量不会被垃圾回收机制回收

用途

  • 匿名自执行函数 - 只需要执行一次,其内部变量无需维护

      (function(){
      //
      })();
  • 封装回调保存作用域(缓存结果)

      for(var i = 1; i < 5; i++) {
          setTimeout((function(i) {
              return function() {
                  console.log(i);        
              } 
          })(i), i * 1000)
      }
  • 模拟私有方法

      var myNameSpace = (function () {
          // 私有计数器变量 
          var myPrivateVar = 0;
      
          /* 记录所有参数的私有函数 */
          var myPrivateMethod = function (foo) {
              console.log(foo + myPrivateVar);
          };
      
          return {
              // 公有变量 
              myPublicVar: 'foo',
              // 调用私有变量和方法的公用函数 *
              myPublicFunction: function (bar) {
                  // 增加私有计数器值 
                  myPrivateVal ++;
      
                  myPrivateMethod(bar);
              }
          };
      })();

常见误区

  • 在循环中创建闭包

      for (var i = 1; i <= 5; i++) {
          setTimeout(function() {
              console.log(i)
          }, i * 1000)
      }
  • 添加监听事件

      function func() {
          var element = document.getElementById("app");
          element.onclick = function() {
              alert(element.id);
          }
      }

知否
221 声望177 粉丝

Skrike while the iron is hot.