节流和防抖通过闭包封装,核心是让内部函数持续访问并修改外部状态变量(如timer、lasttime),避免污染、保证this和参数正确传递;防抖每次触发重置延迟,只执行最后一次,适用于输入搜索等场景;节流固定间隔最多执行一次,适用于滚动等高频场景;两者均需独立实例化、清除定时器防泄漏,并正确绑定this与参数。

节流和防抖用闭包封装,核心是让内部函数能持续访问并修改外部定义的状态变量(比如 timer 或 lastTime),同时避免状态污染、保证 this 和参数正确传递。
防抖:每次触发都重置延迟,只执行最后一次
适用于输入搜索、窗口缩放等“等用户停下再响应”的场景。闭包保存 timer,确保每次调用共享同一计时上下文,又不暴露给全局。
- 用
let timer = null在外层声明,返回的函数通过闭包持续读写它 - 每次触发先
clearTimeout(timer),再设新定时器 - 用
fn.apply(this, arguments)转发上下文和所有参数,避免this丢失 - 支持立即执行模式:首次触发立刻运行,后续连续触发只重置延时
节流:固定间隔最多执行一次
适合滚动、鼠标移动等高频但需节奏稳定的场景。闭包维持时间戳或开关状态,控制执行时机。
- 时间戳版:闭包保存
lastTime = 0,每次比对Date.now() - lastTime >= delay - 定时器版:用
setTimeout占位,期间忽略新调用,到时清空标志再允许下一次 - 两种方式都依赖闭包隔离每个调用实例的状态,互不干扰
- 同样必须用
apply或call保证原方法的this和实参完整传递
绑定到实例时要独立生成,别改原型
如果直接在原型上挂一个带闭包的防抖函数,所有实例会共用同一个 timer,导致行为错乱。安全做法是每个实例单独封装。
- 构造函数或初始化阶段调用防抖/节流函数,传入方法并绑定
this - 把返回的新函数赋值给实例属性(如
this.debouncedSubmit) - 这样每个实例都有自己的闭包作用域,
timer或lastTime互不影响 - 组件卸载前记得清除定时器,防止内存泄漏
注意 this 和参数的传递细节
返回的包装函数默认 this 指向绑定对象(如事件监听器中的 element),不是原始方法定义时的上下文。
- 原始方法若依赖
this访问实例属性,必须提前.bind(this)或在包装函数里用apply - 推荐用
fn.apply(this, arguments),兼容任意数量参数 - 现代写法可用剩余参数
...args,再展开调用fn(...args),但要注意this还是得靠apply或箭头函数捕获
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











