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

关于Function.prototype.defer实现中this指向与apply作用的疑问

问题解答

1. 返回的匿名函数的this指向

函数的this是调用时动态绑定的,和定义位置无关,完全取决于你怎么调用这个返回的匿名函数:

  • 像你示例中f.defer(1000)(1, 2)这种直接独立调用的场景:
    • 非严格模式下:this指向全局对象(浏览器环境是window,Node.js环境是globalThis)
    • 严格模式下:this确实是undefined
  • 如果这个返回函数被作为对象的方法调用,比如obj.deferredFunc = f.defer(1000); obj.deferredFunc(1,2),那this指向调用它的obj对象
  • 如果用call/apply/bind手动绑定this调用该返回函数,this就指向你绑定的目标对象

2. 为什么使用apply,且你的示例能正常运行

示例正常运行的原因

你写的验证函数f(a,b)内部完全没有用到this,所以不管f.apply的第一个参数传什么值,都不会影响f的执行结果。哪怕你直接把f.apply(this, args)改成f(...args),你的示例也会正常弹出3。

此处使用apply的核心目的

这段defer是通用的原型扩展方法,要兼容依赖this的函数的使用场景,保留原函数的this绑定逻辑。举个需要apply的实际例子:

const user = {
  name: "张三",
  sayHi() {
    alert(`你好,我是${this.name}`);
  }
}

// 给sayHi方法增加延迟调用能力
const deferredSayHi = user.sayHi.defer(1000);
// 作为user的方法调用
user.deferredSayHi = deferredSayHi;
user.deferredSayHi(); // 正确弹出「你好,我是张三」

如果defer实现里没有用apply绑定调用时的this,上面的sayHi执行时this就会指向全局对象,无法读取user.name,代码就会出错。
另外补充说明:setTimeout的回调使用了箭头函数,它本身没有独立的this,会继承外层匿名函数的this,所以才能把调用时的this正确透传给原函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:15:04