TypeScript子类属性默认值覆盖父类构造器赋值问题排查
TypeScript子类属性默认值覆盖父类构造赋值的原因解析
先还原你的代码场景,方便理解问题:
abstract class AbstractModel { constructor(data: Partial<AbstractModel>) { Object.assign(this, data); console.log('父类构造器内的age:', this.age); // 输出 10 } } class Derived extends AbstractModel { age = 1; // 子类属性默认值 constructor(data: Partial<Derived>) { super(data); console.log('子类构造器内的age:', this.age); // 输出 1 } } const instance = new Derived({ firstname: 'John', lastname: 'Doe', age: 10 }); console.log('最终实例的age:', instance.age); // 输出 1
核心原因:ES6/TypeScript类的初始化执行顺序
这个现象完全遵循ES6类的标准执行流程,具体步骤如下:
- 调用
new Derived(...)时,先进入子类构造器,第一行必须执行super(data)触发父类构造。 - 父类构造器通过
Object.assign(this, data)将传入的age:10赋值给实例,此时实例的age是10,所以父类构造内打印的是10。 - 父类构造执行完毕后,回到子类构造阶段,优先执行子类自身的实例属性初始化逻辑——也就是
age = 1这一步,这会直接覆盖父类构造中设置的age值。 - 最后执行子类构造器里的剩余代码,此时打印的age已经是被覆盖后的1。
简单来说,子类的实例属性默认值赋值操作,是在父类构造完成后才执行的,所以会覆盖父类构造中对同名属性的赋值。
内容的提问来源于stack exchange,提问作者bleenders
相关产品推荐
相关产品推荐

