防抖节流中this丢失的解决方法有三种:一是用箭头函数自动继承外层this;二是用const self=this显式保存闭包变量并call调用;三是用bind预绑定函数,但性能略低。

在防抖(debounce)和节流(throttle)函数中,this 指向丢失是常见问题——因为定时器回调(如 setTimeout)会丢失原始调用上下文。解决的关键是在闭包中“捕获并绑定”正确的 this,而不是依赖函数调用时的动态绑定。
使用箭头函数自动继承外层 this
箭头函数不绑定自己的 this,而是沿作用域链向上查找,天然适合在闭包中保留调用时的上下文。
function debounce(fn, delay) {
let timer = null;
return function (...args) {
// 箭头函数里的 this 指向外层 function 的 this(即调用 debounce 时 fn 的原始 this)
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args); // ✅ this 正确指向原调用对象
}, delay);
};
}
显式保存 this 到闭包变量
在普通函数中,可在返回函数前用变量缓存 this,避免 setTimeout 内部的 this 变为全局或 undefined。
- 用
const self = this或const ctx = this在闭包顶层保存 - 在定时器回调中用
fn.call(ctx, ...args)显式指定上下文 - 注意:该方式适用于非箭头函数实现,兼容性更好
利用 bind 预绑定执行函数
可提前对 fn 绑定 this 和部分参数,再传入定时器,避免运行时丢失。
function debounce(fn, delay) {
let timer = null;
return function (...args) {
clearTimeout(timer);
// 创建一个已绑定 this 和 args 的新函数(柯里化 + bind)
const boundFn = fn.bind(this, ...args);
timer = setTimeout(boundFn, delay);
};
}
⚠️ 注意:这种方式会在每次调用时重新 bind,有轻微开销;若需高性能,推荐前两种方式。
处理 addEventListener 场景下的 this
当防抖函数用于事件监听器(如 button.addEventListener('click', debounce(handler))),this 默认指向触发事件的 DOM 元素。若 handler 内部依赖 this 指向实例(如 class 方法),需确保:
- handler 是类中通过
bind(this)或箭头属性声明的(如handler = () => {...}) - 或在绑定事件时手动绑定:
debounce(handler.bind(this), 200) - 更推荐在 class 构造器中预绑定,避免重复创建闭包











