Skip to content

闭包

Q:是什么?

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

Q:能干什么?

  • A:

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

      javascript
       //示例
      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
    • 模拟私有方法,闭包可以访问私有函数和变量。

      javascript
      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:

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

      javascript
      //存在闭包
      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);//调用时参数     
        }
    • 将变量值保留到作用域之外