闭包(函数里返回函数)

一.闭包的概念

<script>
      //js作用域: 全局作用域和局部作用域

      /*  function foo() {
        var a = 10;
      }
      foo();
      console.log(a);   →  10 */

      /* function bar() {
        var num = 1;
        function baz() {
          num++;
          console.log(num);
        }
        baz();
      }
      bar();   →  2
      bar();   →  2 */
      function bar() {
        var num = 1;
        function baz() {
          num++;
          console.log(num);
        }
        return baz;
      }
      var foo = bar(); //按照之前的认知,bar执行完毕之后,num这个局部变量应该销毁
      foo(); //   →  2  但foo能正常执行,没有报错,证明num并未销毁,这是为什么呢?
      foo(); //   →  3  就是因为JS闭包这个特性的存在

      //概念:在一个函数的外部能够访问该函数局部变量的函数
    </script>

二.闭包的应用

    <body>
    <ul>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>
    <script>
      //请用闭包实现:点击li,输出对应的索引
      let aLi = document.querySelectorAll("li");
      //非闭包写法************
      /* for (let i = 0; i < aLi.length; i++) {
        aLi[i].onclick = function () {
          console.log(i);
        };
      } */
      //闭包写法**************
      /* for (var i = 0; i < aLi.length; i++) {
        aLi[i].onclick = (function (i) {
          return function () {
            console.log(i);
          };
        })(i);
      } */
      for (var i = 0; i < aLi.length; i++) {
        (function (i) {
          aLi[i].onclick = function () {
            console.log(i);
          };
        })(i);
      }
    </script>
  </body>

三.闭包的优缺点

      <script>
      //优点
      //1.变量能常驻内存
      //2.减少全局变量的定义
      //3.创建命名空间

      let obj = (function () {
        let a = 1;
        function foo() {}
        let b = 2;

        function bar() {}

        return {
          a,
          b,
          foo,
        };
      })();

      //缺点 闭包使用不当,会造成内存污染,正常无法被垃圾回收机制清掉,IE低版本会造成内存泄漏
    </script>

四.垃圾回收机制

	  <script>
      //1. 标记清除
      function foo() {
        var a = 10;
        var b = 20;
      }
      foo();
      //2. 引用计数
      /* var obj = {};
      obj = null; */
      var obj1 = {};
      var obj2 = {};
      obj1.a = obj2;
      obj2.b = obj1;
    </script>

五.闭包面试题

	<script type="text/javascript">
    //*****************************************
    function fun(n, o) {
      console.log(o);
      return {
        fun: function (m) {
          return fun(m, n);
        },
      };
    }
    /*var a = fun(0);
			a.fun(1); //fun(1,0)
			a.fun(2);//fun(2,0);
			a.fun(3);//fun(3,0);*/

    //var b = fun(0).fun(1).fun(2).fun(3);

    /* 	var c = fun(0).fun(1);  
			c.fun(2);
			c.fun(3); */

    //*******************************************
    function fun(n, o) {
      console.log(o);
      return {
        fun: function (m) {
          return fun(m, n);
        }
      };
    }
    // var a = fun(0);a.fun(1);a.fun(2);a.fun(3);
    // var b = fun(0).fun(1).fun(2).fun(3);
    // var c = fun(0).fun(1);c.fun(2);c.fun(3);
    var a = fun(0);
    a.fun(1);
    a.fun(2);
    a.fun(3);
    var b = fun(0).fun(1).fun(2).fun(3);
    var c = fun(0).fun(1);
    c.fun(2);
    c.fun(3);
    //问:三行a,b,c的输出分别是什么?
  </script>

面试题详解链接
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值