• JS 闭包


    先来看个题目

    话说有个函数如下

    function a(){
      let aa = 0;
      function b(){
          aa ++;
          console.log(aa);
      }
      return b;
    }
    

    我们调用方式如下

    //方式一:直接连续调用
    a()(); //1
    a()(); //1
    
    //方式二:赋值之后再调用
    const fn=a();
    fn(); // 1
    fn(); // 2
    

    解释一下,第一种调用方式没有形成闭包,所以aa在a调用完成时就已经被销毁了。
    第二种调用方式作用域转移到了fn上,所以aa并没有随着a的调用完成而销毁,所以第二次输出会在前一次。

    由以上例子可以证明闭包的存在条件,

    1. 作用域嵌套,返回一个作用域,例如一个函数中返回另一个函数
    2. 作用域转移,然后再调用,例如外部函数赋值新变量,执行新变量

    我们对上面题目继续进行变化一下

    1. 变形一:
    function a(){
      let aa = 0;
      console.log(aa);
      function b(){
          aa ++;
      }
      return b;
    }
    
    //调用
    const fn=a();
    fn();
    fn();
    fn();
    

    我们查看控制台打印出什么?,只打印出一个0,调用三次fn只打印出一个0?是的,没错。因为fn每次调用的是b这个函数,a只执行了一次。

    1. 变形二:
    let i=0;
    function a(){
      i++;
      console.log(i);
    }
    
    //调用
    const fn = a;
    fn(); //1
    fn(); //2
    

    如果写成如上形式,那么它是一个闭包吗?答案肯定不是的,

    1. 变形三:
    function a(){
      let aa = 0;
    
      function b(){
          aa ++;
          console.log(aa);
      }
      return b();
    }
    
    // 调用 
    const fn = a;
    fn(); //1
    fn(); //1
    

    如果写成这样,也不会形成闭包,b在return 之前已经执行完成了

    闭包是什么

    函数(局部)作用域转移,该作用域下的变量也跟着转移,导致相关变量不被销毁常驻内存。
    函数里return另一个函数,调用之时进行赋值转移。类似如下结构

    function func1(){
      return function func2(){
        //you code
      }
    }
    const func3=func1();
    

    工作中使用闭包的情况

    1. 防抖和节流
    2. 较大作用域中修改较小作用域中变量的值,私有属性

    参考

  • 相关阅读:
    15款经典图表软件推荐 创建最漂亮的图表
    CSS+JS打造的自适应宽度的滑动门和选项卡
    兼容多浏览器的加入收藏代码
    指针与引用深层次的区别
    反编译winform资源文件
    程序创业必过三关
    自动ping博客服务程序
    C#批量加水印程序
    C#应用程序随机启动
    失败降临是命中注定
  • 原文地址:https://www.cnblogs.com/xingguozhiming/p/13466234.html
Copyright © 2020-2023  润新知