闭包?能做什么?有何优缺点?

428 阅读3分钟

开源

个人开源的leno-admin后台管理项目,前端技术栈:reactHooksant-design;后端技术栈:koamysqlredis,整个项目包含web端electron客户端mob移动端template基础模板,能够满足你快速开发一整套后台管理项目;如果你觉得不错,就为作者点个✨star✨吧,你的支持就是对我最大的鼓励;

演示地址

文档地址

源码github地址

什么是闭包?

闭包本质就是上级作用域内变量的生命周期,因为被下级作用域内引用,而没有被释放。就导致上级作用域内的变量,等到下级作用域执行完以后才正常得到释放。

这句话是我在一篇文章中看到一位网友评论的闭包,我个人感觉非常言简意赅;

闭包怎么诞生的 🥚
其实严格来说,所有的JS函数都是闭包,都会产生闭包;但是因为多数函数的调用和函数的定义都在同一个作用域里面,所以这时闭包的存在与否无关紧要;

举个案例

      let a = 11;
      function fn() {
        let a = 22;
        function fn2() { return a;}
        return fn2();
      }
      fn(); // => 22

其实产生一个闭包非常简单,一个函数加上局部的作用域就能够产生闭包;

闭包有何优点与缺点 ?

优点:

  • 闭包能够延伸变量的作用范围;
  • 闭包可以避免全局变量的污染;

缺点:

  • 因为闭包产生的变量都会常驻在内存中,对内存的消耗非常大,如果滥用闭包,会造成内存泄漏,降低网页的性能;
    解决办法:在退出函数之前,将一些不使用的局部变量全部删除,减轻内存的压力;
  • 在函数的内部再去创建一层函数,其实时不好的做法,因为闭包本身就会影响电脑的处理速度和内存消耗,如果不是非必须使用闭包,尽量减少使用闭包;

闭包能做什么?

1、获取正确的变量 🥩
相信大家都见过一道关于for循环与延迟器的题目,这题就很好展示了闭包如何获取正确的值;
未产生闭包:

       for (var i = 0; i < 5; i++) {
        setTimeout(function () {
          console.log(i);  // => 5个 5
        }, 500);
      }

解决问题:

    for (let i = 0; i < 5; i++) {
        setTimeout(function () {
          console.log(i); // =>  0 1 2 3 4
        }, 500);
      }

其实只要把全局变量替换成局部变量就会产生闭包;

2、外部能够读取内部里的变量 🥫

      function f1() {
        var n = 11;
        function f2() {
          return 11 + 11;
        }
        return f2;
      }
      var res = f1();
      console.log(res()); // => 22

3、节流与防抖 💨

// 节流
function throttle() {
    let flag = falsereturn function () {
        if(timer) return
        flag = setTimeout(() => {
            console.log(11);
            flag = false
        },500)
    }
}

// 防抖
function debounce(){
    let timer = false
    return function(){
        clearTimeout(timer)
        timer = setTimeout(() => {
           console.log(11);
        },500)
    }
}

4、自调用函数 🥝

自调用函数也会产生闭包fn函数;

    var a = 11;
    (function fn() {
       console.log(a);
      })()

总结

闭包我个人理解其实是为了保护函数内部的变量不受外部干扰,实现一些属性和方法的私有化,如果文章有不正确之处,欢迎大家指出,谢谢!