You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

防抖函数中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 03:05:07