关于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
相关产品推荐
相关产品推荐

