JavaScript继承:子类属性在父类构造函数未正确生效的问题
问题原因
你遇到的问题源于类实例字段的初始化时机:
- 像
id = "A"这类直接在类中声明的实例字段,会在构造函数执行的特定阶段完成赋值。对于子类B来说,会先调用父类A的构造函数(通过super()),此时子类的id = "B"还未执行,父类构造函数里的this.id还是父类初始化的"A"。 - 父类构造函数执行完毕后,子类的实例字段才会完成赋值并覆盖原有的"A",所以第二次调用
show()时输出的是"B"。
解决方案
要让父类构造函数中能获取子类的属性值,有两种常用方案:
方案一:用Getter方法替代实例字段
将id定义为原型上的getter方法,子类重写该方法后,父类构造函数中访问this.id会动态调用子类的getter:
class A { get id() { return "A"; } constructor() { this.show(); } show() { console.log(this.id); } } class B extends A { get id() { return "B"; } } const o = new B(); o.show();
这段代码会输出两次"B",因为父类构造函数调用show()时,this指向子类实例,访问this.id会优先调用子类B的getter方法。
方案二:调整方法调用时机
如果业务允许,避免在父类构造函数中调用实例方法,将初始化逻辑移到子类构造函数中:
class A { id = "A"; constructor() { // 不在父类构造函数中调用show() } show() { console.log(this.id); } } class B extends A { id = "B"; constructor() { super(); this.show(); // 子类构造函数中调用,此时id已初始化 } } const o = new B(); o.show();
这种方式也能输出两次"B",因为调用show()时子类的id已经完成赋值。
内容的提问来源于stack exchange,提问作者AMADANON Inc.
相关产品推荐
相关产品推荐

