JavaScript类继承中默认值赋值的特殊行为原因咨询
JavaScript类继承中类字段与getter的行为差异解析
类字段赋值的案例
class Parent { defaultValue = 1; value = this.defaultValue; } new Parent() // {defaultValue: 1, value: 1} class Child extends Parent { defaultValue = 2; } new Child() // {defaultValue: 2, value: 1}
创建Child实例时,value最终取值为父类的defaultValue(1),而非子类定义的2。
改用getter后的案例
class Parent { get defaultValue() { return 1; } value = this.defaultValue; } new Parent() // {defaultValue: 1, value: 1} class Child extends Parent { get defaultValue() { return 2; } } new Child() // {defaultValue: 2, value: 2}
此时Child实例的value能正确获取子类defaultValue的取值(2)。
行为差异的核心原因
类字段的执行逻辑:类字段的赋值操作属于类构造阶段的逻辑。创建子类实例时,会先执行父类的初始化流程(包括父类的类字段赋值),此时子类的
defaultValue字段还未完成初始化(子类的类字段要在父类构造逻辑执行完毕后才会赋值到实例上)。因此父类中value = this.defaultValue读取的是父类自身的defaultValue,后续子类的defaultValue会覆盖实例上的同名属性,但value已经完成赋值,不会再更新。getter的原型链特性:getter是挂载在类的原型对象上的方法,子类定义的同名getter会直接覆盖父类原型上的对应方法。当父类中执行
value = this.defaultValue时,this指向的是子类实例,通过原型链查找defaultValue时,会优先匹配子类原型上的getter,因此返回子类定义的取值。
简短总结
- getter(以及类方法)会在原型链中被子类重写,父类逻辑调用时会使用子类的重写结果;
- 直接赋值的类字段仅在对应类的构造阶段执行,子类的类字段初始化晚于父类逻辑,因此父类读取不到子类的类字段值。
内容的提问来源于stack exchange,提问作者vinger
相关产品推荐
相关产品推荐

