防抖函数返回值能否用箭头函数?为何会出现this为undefined错误?
防抖函数返回值能否使用箭头函数的问题解答
核心结论
防抖函数返回的包装函数不建议改写为箭头函数,改写后触发this为undefined报错的本质是JavaScript中普通函数与箭头函数的this绑定规则存在根本差异。
正常工作的实现逻辑
可全局复用的通用防抖标准实现如下:
export const debounce = (callback: Function, ms = 300) => { let timeoutId: ReturnType<typeof setTimeout> return function (...args: any[]) { clearTimeout(timeoutId) timeoutId = setTimeout(() => callback.apply(this, args), ms) } }
这个版本中返回的是function关键字声明的普通函数,它的this遵循动态绑定规则:
- 函数执行时的
this值由调用方决定,和函数定义的位置无关 - 比如将防抖后的函数绑定为DOM事件回调、类组件方法时,
this会自动指向触发事件的DOM元素、组件实例,后续通过callback.apply(this, args)可以把正确的上下文和参数透传给原回调,适配全场景复用需求。
箭头函数版本报错的底层原因
改写为箭头函数的问题代码如下:
export const debounce = (callback: Function, ms = 300) => { let timeoutId: ReturnType<typeof setTimeout> return (...args: any[]) => { clearTimeout(timeoutId) timeoutId = setTimeout(() => callback.apply(this, args), ms) } }
箭头函数本身不持有自己的this,它的this值在函数定义时就被静态绑定为外层作用域的this,后续无论用什么方式调用,都不会改变这个this的指向:
- 外层的
debounce本身也是箭头函数,它的外层作用域是ES模块顶层(当前前端工程绝大多数采用ES模块规范),ES模块顶层的this默认就是undefined - 因此返回的箭头函数中能拿到的
this永远是undefined,执行callback.apply(this, args)时会把原回调的上下文强制设为undefined,只要原回调中用到了this相关逻辑,就会触发undefined报错。
补充说明
如果一定要使用箭头函数书写返回逻辑,需要放弃隐式this透传的能力,改为显式传递上下文,但这种实现无法兼容依赖隐式this的调用场景,作为通用工具函数的适配性会大幅下降,因此通用防抖的实现更推荐用普通函数作为返回的包装函数。
内容的提问来源于stack exchange,提问作者NN N
相关产品推荐
相关产品推荐

