防抖函数中e.currentTarget为何为null?
问题原因及解决办法
核心原因
事件对象(Event)的生命周期和当前事件处理流程绑定:当浏览器完成当前事件的同步处理后,会自动清理事件对象的currentTarget引用,把它设为null。
你的防抖函数用setTimeout延迟了textLog的执行——等setTimeout触发时,原本的输入事件已经处理完毕,事件对象的currentTarget自然就被清掉了。而target是事件触发的原始DOM节点(也就是那个input),它是真实存在的元素,不会被事件流程回收,所以一直有有效值。
另外你用func.call(null, arg)调用函数时,把this绑定成了null,就算事件对象没被回收,currentTarget也没法正确指向绑定事件的元素,但这不是主要问题,核心还是事件对象的生命周期限制。
修复方案
方案1:提前保存需要的属性(推荐)
既然事件对象会被回收,就在事件触发的同步阶段把需要用的值(比如input的value)存下来,延迟执行时直接用这个值,不用传整个事件对象:
const textLog = (value) => { console.log('--textLog start--'); console.log('输入值:', value); console.log('--textLog end--'); }; const debounce = (func, wait) => { let timeOutId; return (arg) => { const inputValue = arg.target.value; // 同步阶段保存值 if (timeOutId) { clearTimeout(timeOutId); } timeOutId = setTimeout(() => { func(inputValue); }, wait); }; };
方案2:直接传递绑定事件的元素
因为currentTarget本质就是绑定事件的DOM元素(也就是你的input),可以直接把这个元素的引用传进去,不用依赖事件对象:
const textLog = (element) => { console.log('--textLog start--'); console.log(element.value); console.log('--textLog end--'); }; const debounce = (func, wait) => { let timeOutId; return function(arg) { // 用普通函数保留this指向绑定事件的元素 const currentElement = this; // this就是input元素 if (timeOutId) { clearTimeout(timeOutId); } timeOutId = setTimeout(() => { func(currentElement); }, wait); }; };
内容的提问来源于stack exchange,提问作者pop
相关产品推荐
相关产品推荐

