类实例化用.call无效,跨类方法调用出现this指向错误求助
我来帮你梳理这个问题,你遇到的TypeError: this.doSomething2 is not a function本质是类实例中this指向的问题,咱们一步步拆解解决:
问题根源:类实例中this的默认指向
首先要明确:ES6类的方法里,this默认指向当前类的实例。所以当你在MainClass里实例化ClassA后,ClassA的doSomething1方法里的this是ClassA的实例,而不是MainClass的实例——自然找不到doSomething2方法。
你之前尝试用.bind()/.call()没生效,是因为用错了地方:
new ClassA().bind(this)无效:.bind()是函数的方法,new ClassA()返回的是对象实例,不是函数,所以没法调用.bind()。- 直接对类构造函数用
ClassA.call(this):ES6类必须通过new调用,这么做会直接报错;就算是ES5的构造函数,这么做也只是把ClassA的属性挂载到MainClass实例上,不是真正的实例化ClassA,不符合你的需求。
两种可行的解决方案
方案1:实例化ClassA时传入MainClass的实例引用
这是最直观的方式,让ClassA持有MainClass的实例,直接通过引用调用方法:
// classA.js export class ClassA { constructor(mainInstance) { // 保存MainClass的实例引用 this.mainInstance = mainInstance; } doSomething1() { // 通过引用调用MainClass的方法 this.mainInstance.doSomething2(); } }
// index.js import { ClassA } from './classA.js'; class MainClass { constructor() { // 实例化ClassA时传入当前MainClass的实例(this) this.classA = new ClassA(this); // 调用ClassA的方法 this.classA.doSomething1(); } doSomething2() { console.log('MainClass 的 doSomething2 方法被触发了!'); } } new MainClass();
方案2:将ClassA的方法绑定到MainClass实例
如果不想修改ClassA的构造函数,可以在MainClass里把ClassA的方法的this绑定到自身实例:
// classA.js export class ClassA { doSomething1() { // 现在this会指向MainClass的实例 this.doSomething2(); } }
// index.js import { ClassA } from './classA.js'; class MainClass { constructor() { this.classA = new ClassA(); // 把ClassA的doSomething1方法绑定到MainClass的实例 this.classA.doSomething1 = this.classA.doSomething1.bind(this); // 调用绑定后的方法 this.classA.doSomething1(); } doSomething2() { console.log('MainClass 的 doSomething2 方法被触发了!'); } } new MainClass();
关于“实例化类时如何使用.call()”的疑问
ES6类的构造函数必须通过new操作符调用,直接用.call()/.apply()调用类构造函数会抛出Class constructor X cannot be invoked without 'new'的错误。
如果是想改变构造函数内部的this指向,通常是用于继承场景——比如子类调用父类构造函数时,super()其实就等价于Parent.call(this, ...args):
class Parent { constructor(name) { this.name = name; } } class Child extends Parent { constructor(name, age) { // 等价于 Parent.call(this, name) super(name); this.age = age; } }
如果是想让类实例的方法this指向外部对象,更合适的方式是前面提到的“传入实例引用”或“绑定方法this”,而不是在new的时候用.call()。
内容的提问来源于stack exchange,提问作者bonblow
相关产品推荐
相关产品推荐

