防抖的核心是只执行最后一次触发的回调,通过闭包保存timer并用settimeout清除重设实现;支持immediate选项,需正确传递this和参数,适用于搜索等高频终态响应场景。

防抖(Debounce)的核心是:在事件频繁触发时,只执行最后一次触发后的回调,中间的触发全部忽略。用 setTimeout 和闭包就能轻松实现,不需要额外依赖。
基本原理:清除旧定时器,重设新定时器
每次触发函数时,先清除之前设置的定时器(如果存在),再新建一个定时器。这样只有最后一次触发会“存活”到延迟结束并执行。
- 用一个变量(如
timer)保存当前定时器 ID - 每次调用防抖函数时,先
clearTimeout(timer) - 再用
setTimeout设置新的延迟执行逻辑 - 闭包确保
timer在多次调用间保持引用
手写一个可复用的防抖函数
下面是一个简洁、带立即执行选项的版本:
function debounce(func, wait, immediate = false) {
let timer = null;
return function(...args) {
const later = () => {
timer = null;
if (!immediate) func.apply(this, args);
};
const callNow = immediate && !timer;
clearTimeout(timer);
timer = setTimeout(later, wait);
if (callNow) func.apply(this, args);
};
}
使用示例(搜索框输入防抖):
const search = debounce(() => {
console.log('发起搜索请求');
}, 300);
input.addEventListener('input', search);
注意 this 和参数的正确传递
防抖函数内部要保留原始调用的上下文和参数:
- 用
func.apply(this, args)确保this指向正确(比如事件监听器中的this是 DOM 元素) - 用剩余参数
...args收集所有传入参数,避免丢失 - 不要直接写
func(),否则会丢失this和实参
实际使用中的常见细节
防抖不是万能的,要注意适用场景和边界情况:
- 适合输入搜索、窗口缩放、滚动等高频但只需响应最终状态的场景
- 不适用于需要即时反馈的操作(如按钮点击反馈),这时该用节流或直接执行
- 如果用户连续快速操作后停止,延迟时间从最后一次触发开始计时
- 页面卸载前建议手动清除定时器(尤其在单页应用中),避免内存泄漏
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











