闭包(从0基础的角度谈闭包是什么,以及闭包的应用(防抖))

189 阅读3分钟

声明:0基础学的前端,很多地方可能说法是错误,欢迎指点,自己只是记录

首先我们先来说需求,比如:我们需要根据客户的选择来切换数据,这个时候客户在1秒内点了5个不同的按钮,数据量如果太大的话,我们肯定不能在1秒内发送5次请求,所以我们等客户停止点击后1秒钟后才发送请求,显示客户最终想要的结果,这个时候就用到了防抖,我们先模拟写下初始代码

<button>添加</button>
<script>
  document.querySelector('button').addEventListener('click', fn)
  function fn(){console.log(123)}
</script>

那么什么是防抖:用最最最小白的话来说,防抖就是开个定时器,然后每次点击如果发现定时器是开启的,就关闭定时器,再去重新开启新的定时器,下面的正确的逻辑,错误的代码

  document.querySelector('button').addEventListener('click', fn),
  function fn() {
     //创建一个变量
    var timer;
    //如果定时器有值,那么就停止定时器
    if (timer) {
      clearTimeout(timer)
    }
    //否则就开始定时器
    timer = setTimeout(() => {
      console.log(123);
    }, 1000)
  }

上面的代码按照普通人的逻辑来说是对的,但是狂点按钮定时器停止后并没有按照想象的那样,点击停止后隔一秒才出现123,那么是哪一步出现问题,就是var timer;这一句代码 每次点击调用fn函数的时候,都重复声明了timer,并且它的值每次都会空,所以定时器并没有被成功赋值给timer,所以导致了定时器每次点击都会执行

这个时候我们发现问题了,timer不应该被重复声明,重复赋值,只需要声明一次,这个时候把代码改成这样

  document.querySelector('button').addEventListener('click', fn)
  var timer;
  function fn() {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      console.log(123);
    }, 1000)
  }

在全局中,我们的timer变量只声明了一次,我们每次点击的时候都调用了fn函数,并没有每次都重复声明,这就成功实现了防抖的一个功能,但是这样把变量暴露在全局肯定是不行的,所以我们需要把变量保护起来,所以我们还是得用一个函数把这段代码包裹起来,然后我们再次改代码,这个时候就用到了闭包

  // 这句代码中fn调用了一次,并且把fn的返回值给了fangdou这个变量,所以我们以后每次调用fangdou,执行的都是fn里的返回值
  //注意这句代码要放在document代码上方,不然当js执行带document的时候,找不到fangdou这个函数
  var fangdou =fn()
  document.querySelector('button').addEventListener('click', fangdou) 
  function fn() {
    var timer;
    return function () {
      //根据对函数作用域链的理解,函数体里面可以访问外面的变量
      if (timer) {
        clearTimeout(timer)
      }
      timer = setTimeout(() => {
        console.log(123);
      }, 1000)
    }
  }

在上面这段代码中,我们将timer重新包裹了起来,在fn函数中我们返回了一个函数,我们将fn赋值给了fangdou,fn刚好执行了一次,只声明了一次timer,然后返回了一个函数,以后每次调用fangdou其实执行的是fn返回的函数体,不会再去执行fn这个函数,这就形成了一个闭包,

最后总结闭包是什么?

1.函数的嵌套,2.内部函数引用外部函数的变量3.外部函数返回值必须是内嵌函数

//记得最后解绑事件和消除闭包,不然会造成内存泄漏哟
var fangdou= null
document.querySelector('button').removeEventListener('click', fangdou)

以上就是闭包和防抖的最简单的应用!