JavaScript中通过引用调用类方法时如何让this仍指向原类实例
问题复现
你给出的示例代码如下,运行时myfoo.f内部的this会丢失原实例绑定,无法输出预期的10:
class foo(){ constructor(){this.x = 10} f(){console.log(this.x)} } myfoo = new foo() class bar{ constructor() b(func){func()} } mybar = new bar() mybar.b(myfoo.f)
解决方案
有三种常用的稳定修复方式:
- 方案1:手动绑定this
传递函数时调用bind方法,将f的this永久绑定到myfoo实例:
也可以在类构造函数内提前完成绑定,后续调用无需重复处理:mybar.b(myfoo.f.bind(myfoo))class foo(){ constructor(){ this.x = 10 this.f = this.f.bind(this) } f(){console.log(this.x)} } - 方案2:用箭头函数定义类方法
箭头函数的this继承自外层词法作用域,不会随调用方式改变:class foo(){ constructor(){this.x = 10} f = () => {console.log(this.x)} } - 方案3:用箭头函数包裹调用
保证f是作为myfoo的方法被调用,此时this会自动指向myfoo:mybar.b(() => myfoo.f())
this动态绑定规则的设计原因
JavaScript的this采用运行时动态绑定的设计,核心有两个考量:
- 提升函数复用性,降低内存开销
同一个函数可以绑定到不同的对象上调用,不需要为每个对象单独创建函数副本,非常契合JavaScript早期轻量脚本的定位。比如多个实例共享同一个原型方法,不用每个实例都存储一份函数数据。 - 适配事件驱动的原生使用场景
JavaScript最初是为浏览器交互设计的,事件回调函数的this默认指向触发事件的DOM元素,这种动态绑定的规则可以让开发者不用手动传递上下文,写事件处理代码时更简洁。
作为动态语言,这种灵活的绑定规则也给了开发者更高的自由度,可以通过call、apply、bind手动控制this的指向,适配不同的业务需求。
内容的提问来源于stack exchange,提问作者smaillis
相关产品推荐
相关产品推荐

