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

JavaScript函数延迟包装器问题:解决this上下文丢失问题

解决setTimeout丢失函数上下文的问题

嘿,这个问题我太熟悉了!咱们先搞明白为啥调用defer的时候会输出undefined:当你把函数直接传给setTimeout时,它执行的时候默认的this会指向全局对象(浏览器里是window,Node.js里是global),完全跟原来的obj1/obj2没关系了,自然拿不到someProp。

下面给你几种靠谱的解决方案,随便选一种都能搞定:

方案1:用箭头函数继承上下文

箭头函数不会创建自己的this,它会继承外层作用域的this——也就是defer方法被调用时的this(也就是obj1或者obj2)。修改后的代码如下:

function someFunc() { console.log(this.someProp); }
var obj1 = { someProp: 1, method1: someFunc, };
var obj2 = { someProp: 2, method2: someFunc, };

Function.prototype.defer = function(ms) {
  setTimeout(() => {
    this(); // 这里的this就是原来的obj1/obj2
  }, ms);
};

obj1.method1(); // 1
obj2.method2(); // 2
obj1.method1.defer(1000); // 1 after 1 sec
obj2.method2.defer(1000); // 2 after 1 sec

方案2:用bind绑定固定上下文

bind方法会返回一个新函数,这个函数的this会被永久绑定到你传入的对象上。这里我们把当前的this(也就是obj1/obj2)绑定给原函数:

Function.prototype.defer = function(ms) {
  setTimeout(this.bind(this), ms);
};

方案3:手动保存上下文到变量

这是ES6之前常用的方式,把当前的this存到一个变量里,在setTimeout的回调里调用这个变量指向的函数:

Function.prototype.defer = function(ms) {
  const context = this;
  setTimeout(function() {
    context(); // 这里的context就是原来的obj1/obj2
  }, ms);
};

这三种方案都能完美保留函数的上下文,你可以根据自己的代码风格选择~

内容的提问来源于stack exchange,提问作者sandbox992

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:29:31