防抖函数核心是“等用户停下来再执行”,通过每次触发时clearTimeout旧定时器并设置新定时器实现;支持leading(首次立即执行)、trailing(末次延迟执行)、cancel(清空任务)和flush(立即执行);正确传递this与参数,使用function声明和apply/call确保上下文与参数完整性。

防抖函数的核心是“等用户停下来再执行”,不是每次触发都立刻调用,而是重置计时器,只在最后一次触发后延迟执行。
关键逻辑:每次触发都清除旧定时器,设置新定时器
防抖不是简单地加个 setTimeout,而是必须在每次新事件到来时,先 clearTimeout 清掉上一次还没执行的定时器,再启动新的定时器。否则,多次快速触发会导致多次执行,失去防抖意义。
- 没有 clearTimeout → 多个定时器并存 → 多次执行(错误)
- 有 clearTimeout + 新 setTimeout → 只保留最后一次的延时任务(正确)
立即执行选项(leading)需要单独控制首次触发
标准防抖默认只在停止触发后执行(trailing)。如果想让第一次触发立刻执行,就得加 leading 参数,并用一个标志位记录是否已执行过首次。重点在于:leading 和 trailing 可以同时为 true,但不能让首次和末次重复执行,需用 isInvoking 标志避免冲突。
- leading 为 true 时,第一次触发立即执行,并设 isInvoking = true
- 后续触发不执行,只重置定时器;定时器到期时,若 isInvoking 已为 true,则不再执行(防止重复)
- 定时器回调里要重置 isInvoking,保证下一轮正常响应
取消(cancel)和刷新(flush)是实用增强能力
实际使用中常需要手动干预:比如表单还没提交就跳转了,该清掉待执行的任务;或者用户突然点“确认”,希望立刻执行而非等待延迟。cancel 是清空所有待执行状态,flush 是强制立即执行当前排队的任务(如果有)。
立即学习“Java免费学习笔记(深入)”;
- cancel 要清 timerId、重置 isInvoking、清 pendingArgs/pendingThis 等缓存
- flush 判断是否有 pending 状态,有则立刻用 apply 执行,再清空
- 两者都应返回 undefined 或 void,不干扰原函数语义
this 和参数必须正确传递,支持不定参和上下文
防抖包装后的函数仍要像原函数一样能接收任意参数、保持 this 指向。不能写成 () => {}(会丢失 this),也不能只取 arguments[0](漏参数)。正确做法是用 rest 参数收集,apply 绑定 this 和参数数组。
- 使用 function 声明而非箭头函数,确保 this 由调用时决定
- 用 ...args 收集全部参数,call/apply 传给原函数
- pendingArgs 存的是 args 数组,pendingThis 存的是当前 this,flush 时再还原调用


















