手写工具函数系列--手写防抖函数

44 阅读2分钟

什么是防抖?

这是一个在前端开发中非常常见且重要的性能优化技术。

当一个事件(如用户输入、窗口调整、页面滚动)被频繁触发时,函数不会立即执行,而是等待一段固定的时间。如果在这段固定时间内,该事件没有再被触发,那么函数才会真正执行。
以下是代码实现过程

const btn = document.querySelector("#btn")
function fn(a) {
    console.log(a);
    //console.log(this);
}
function debounce(callback, delay) {
    let timer;
    return function (...args) {
        clearTimeout(timer)
        timer = setTimeout(() => {
            callback.apply(this, args)
        }, delay)
    }
}
 btn.addEventListener("click", debounce(fn, 1000, 12))

分析

  1. 闭包
  2. this指向

1. 闭包

为什么需要用到闭包?
防抖函数的作用在于,在给定的时间范围内,如果事件多次触发,在多次触发的过程当中,新的触发会把旧的触发覆盖掉,完成这个效果需要把定时器清除。如果定时器给全局变量接收,防抖函数被多个按钮使用的话,多个按钮的定时器就共用一个全局变量,在不同按钮不同的点击事件触发过程中,全局变量始终只存着最新触发的定时器状态,其它的定时器状态遗失。
而利用闭包的记忆特点,可以将接收定时器的变量私有化,每次点击调用防抖函数时,能够记住之前的操作状态,同时保持这些状态的私密性和独立性。

2. this指向

为什么需要让this指向元素?
以下代码没有让this指向元素的效果:

const btn = document.querySelector("#btn")
function fn(a) {
    console.log(a);
    //console.log(this);
}
function debounce(callback, delay) {
    let timer;
    return function () {
        clearTimeout(timer)
        timer = setTimeout(callback, delay)
    }
}
 btn.addEventListener("click", debounce(function(){
     console.log(this)//window
 },3000))

可以看出,如果不让回调指向元素,就无法对元素进行操作,也不符合行为直觉