JavaScript Public class fields类字段默认值无法被构造传参覆盖问题求解
问题根因
该现象是ES公共类字段的初始化执行顺序导致的,子类实例化的执行流程如下:
- 触发父类构造函数执行
- 父类构造中调用
set方法,已经成功将实例的Values属性赋值为[1,2] - 父类构造执行完毕后,才会执行子类公共类字段的初始化逻辑,直接把之前赋值的
Values覆盖为默认的空数组[],所以最终输出是空数组。
解决方案
方案1:改动最小,仅调整子类字段声明
修改子类Values字段的赋值逻辑,仅当实例上不存在Values属性时才用默认空数组:
class Child extends Parent { // 已存在赋值则沿用,无值才用默认空数组 Values = this.Values ?? []; }
该方案无需修改父类逻辑,完全保留默认值配置的需求。
方案2:调整赋值时机,等子类字段初始化完成后再赋值
修改父类构造的执行时机,把赋值逻辑放到同步任务执行完成后再跑:
class Parent { constructor(args) { // 等待子类字段初始化完成后再执行赋值 queueMicrotask(() => this.set(args)); } set(field, value) { for (const key in field) { Reflect.set(this, key, field[key]); } console.log('Parent after setting:', this.Values) } }
如果需要同步获取值,也可以给子类补充构造函数,父类构造执行完后主动调用set:
class Child extends Parent { Values = []; constructor(args) { super(); this.set(args); } }
验证结果
修改后运行代码,输出符合预期:
Parent after setting: [1,2] Child getting: [1,2]
内容的提问来源于stack exchange,提问作者incutonez
相关产品推荐
相关产品推荐

