Skip to main content

闭包

Q:是什么?

  • A:
    • 够读取其他函数内部变量的函数,是将函数内部和函数外部连接起来的一座桥梁。——by:阮一峰
    • 词法表示包括不被计算的变量的函数。——by:W3school
    • 函数以及其捆绑的周边环境状态lexical environment词法环境的引用的组合。——by:MDN

Q:能干什么?

  • A:

    • 可以从内部函数访问外部函数的作用域,允许将函数与其所操作的某些数据(环境)关联起来。

       //示例
      function makeAdder(x) {
      return function (y) {
      return x + y;
      };
      }

      //此时传入makeAdder中的x
      var add5 = makeAdder(5);
      var add10 = makeAdder(10);

      //此时传入makeAdder中的y,但是函数会记住之前传的x
      console.log(add5(2)); // 7
      console.log(add10(2)); // 12
    • 模拟私有方法,闭包可以访问私有函数和变量。

      var Counter = (function () {
      var privateCounter = 0;
      function changeBy(val) {
      privateCounter += val;
      }
      return {
      increment: function () {
      changeBy(1);
      },
      decrement: function () {
      changeBy(-1);
      },
      value: function () {
      return privateCounter;
      },
      };
      })();

      console.log(Counter.value()); /* logs 0 */
      Counter.increment();
      Counter.increment();
      console.log(Counter.value()); /* logs 2 */
      Counter.decrement();
      console.log(Counter.value()); /* logs 1 */
    • 让变量的值始终保持在内存中。

Q:什么时候被创建?

  • A:随着函数的创建而被同时创建。

Q:闭包的缺点是什么?

  • A:在处理速度和内存消耗方面对脚本性能具有负面影响

Q:如何避免闭包?

  • A:

    • 将异步获取值保留到新增的闭包中

      //存在闭包
      for(var i = 0;i < 10;i++){
      setTimeout(()=>{console.log(i),1000})
      }

      //优化
      function init3() {
      var pAry = document.getElementsByTagName("p");
      for( var i=0; i<pAry.length; i++ ) {
      //嵌套多一层闭包
      (function(arg){
      pAry[i].onclick = function() {
      alert(arg);
      };
      })(i);//调用时参数
      }
    • 将变量值保留到作用域之外