什么是闭包?闭包的应用

本文参考: 原文链接:https://blog.csdn.net/lk19910323/article/details/124605163

闭包:简单的理解就是 函数嵌套函数,内层函数可以访问外层函数中的变量,参数

function bibao(fn, wait) {
  const a = 123;
  return function () {
    fn();
    console.log(wait, a);
  }
}

有时候需要用到函数内的局部变量,在正常情况下是不能读取到的,这个时候就需要用到闭包。
闭包可以封装对象的私有属性和方法,vue 中的 data 就是一种闭包的形式。
闭包作为回调函数,可以实现函数的复用

优点:闭包因为长期驻扎在内存中。可以重复使用变量,不会造成变量污染
缺点:闭包会使函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,可能会导致内存泄露。解决方法是在退出函数之前,将不使用的变量全部删除。

或者
闭包的三个特性
1:函数套函数
2:内部函数可以直接访问外部函数的内部变量或参数
3:变量或参数不会被垃圾回收机制回收 GC

 

闭包的应用场景 

1、闭包作为回调函数,可以实现函数的复用

2、防抖 节流

// 防抖点击之后过了wait才响应,如果一直点,就一直没有响应,直到你停下来后,wait后执行。一进来就清,然后wait后再做
export function antishake<T>(fn: T, wait: number): () => void { //第一个参数是函数 第二个参数是毫秒值
  let timer: NodeJS.Timeout //声明一个变量来接收延时器 初始值为null
  return (...args) => {
    clearTimeout(timer)
    timer = setTimeout(() => {
      typeof fn === 'function' && fn(...args) //调用这函数
    }, wait);
  }
}

// 节流, 每wait执行一次,如果你一直点,就过2s执行一次,过wait再执行一次。<br /> 节流是 一进来就先看有没有,有的话就啥都不做,没有的话再做 ,做完清
export function throttle<T>(fn: T, wait: number): () => void {
  let timer: NodeJS.Timeout | null //节点闸
  return function (...args) {
    if (timer) return //null false 不是null结果减少true 如果上传没有我就直接跳过 没有人我就上去
    timer = setTimeout(() => {
      typeof fn === 'function' && fn(...args) //调用这函数
      timer = null //做完之后重新关闭节点闸
    }, wait);
  }
}

 

以下内容转自: https://www.jianshu.com/p/673b5346e97e?ivk_sa=1024320u

强大的节流函数  最新的需求是这样的,事件第一次触发的时候我要执行该函数,事件停止后,也要再触发一次函数。  

有点复杂,我看不太明白。

有需要的可以研究下

function throttle(func, wait, options = {}) {
  let timeout,
    previous = 0

  return function() {
    let now = +new Date()
    let remain = wait - (now - previous)

    if (remain < 0) {
      if (previous === 0 && !options.begin) {
        previous = now
        return
      }

      if (timeout) {
        clearTimeout(timeout)
        timeout = null
      }

      previous = now
      func.call(this, arguments)
    } else if (!timeout && options.end) {
      timeout = setTimeout(() => {
        func.call(this, arguments)
        timeout = null
      }, wait)
    }
  }
}

 

这样就完成了强大的节流函数了, 第一次来的时候,可以执行一次回调函数,结束的时候也会执行一次回调函数。并且可以通过options来配置。

如果设置了options.begin === true就第一触发事件就立刻会执行回调函数。因为我们设置previous的的初始值为0,所以如果previous === 0就表示是第一次触发该事件,options.begin就可以得出第一次是否执行该回调函数。

如果设置了options.end === true事件停止触发后也会执行一次该回调函数。其实在事件触发的整个时间内,定时器中的回调函数从来都没有被执行过,只有在事件停止出发后,定时器内的回调函数才被执行。只要设置了options.end就相当于只是用计算时间的方式来实现节流



作者:js好难学啊
链接:https://www.jianshu.com/p/673b5346e97e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

posted @ 2022-12-08 14:51  飞奔的程序员  阅读(607)  评论(0)    收藏  举报