JavaScript 防抖 原理 图解

197 阅读2分钟

JavaScript 防抖函数是一种常见的优化技术,它可以在用户连续触发某个事件时只执行最后一次触发的操作,以避免频繁的操作。

例如,当用户在搜索框中连续输入字母时,防抖函数可以延迟执行搜索操作,只在用户停止输入一段时间后才真正执行搜索。 JavaScript 防抖函数的原理是利用了定时器和闭包的特性。

原理

触发事件 -> 设置计时器 -> 前面有计时器清除(中断时间处理函数的运行) -> 调用

当防抖函数第一次被调用时,它会记录当前的上下文和参数,并设置一个计时器,计时器的时间间隔由防抖函数的第二个参数 delay 决定。如果在这段时间内,防抖函数再次被调用,它会清除之前的计时器,并重新设置一个新的计时器。因此,在 delay 毫秒内连续调用防抖函数时,计时器会被不断地清除和设置,直到最后一次调用。

当最后一次调用发生时,计时器会等待 delay 毫秒后才执行防抖函数的真正操作。因此,只有最后一次调用会被真正执行,前面的调用都会被清除,从而避免了频繁的操作。

闭包的作用在于,防抖函数内部返回一个新的函数,该函数可以访问防抖函数内部的变量。这样,在新的函数被连续调用时,它可以访问到之前设置的计时器 ID,并清除它,从而实现防抖的效果。

图解

image.png

细节处理

由于函数实现返回函数里面执行的,所以this指向window 而this应该指向函数调用者dom对象, thisnewHandler传入debounce,记录this的值 将arguments事件对象,使用apply将函数内部this指向为dom对象,将arguments事件对象传入参数,

在这个例子中,当 newHandler 函数作为事件监听函数被调用时,this 值确实是绑定了事件的 DOM 元素。然后 newHandler 函数内部调用了 debounce 函数,此时 debounce 函数内部的 this 值也会变成 DOM 元素。 所以,debounce 函数内部的 this 值就是绑定了事件的 DOM 元素。在 debounce 函数内部,我们将这个值保存到了 curThis 变量中,然后在闭包函数内部使用了 fn.apply(curThis, args) 将其传递给了回调函数。

代码实现

image.png

实验demo

image.png