扩展含私有属性的单例类时出现重复初始化私有成员错误
单例类继承后私有字段重复初始化报错的解决方法
你遇到的问题核心是父类A的单例逻辑和子类B的私有字段初始化机制冲突,具体原因如下:
第一次执行new B()时:
- JS引擎创建B的实例,完成私有字段
#b=2的初始化 - 进入A的constructor,此时
A.#instance为null,将当前B实例赋值给A.#instance并返回
第二次执行new B()时:
- 引擎仍会尝试创建新的B实例框架,准备初始化
#b - 进入A的constructor后直接返回已存在的
A.#instance(即第一次的B实例) - 引擎发现要给同一个对象重复初始化私有字段
#b,但私有字段在对象生命周期内仅能初始化一次,因此抛出Cannot initialize #b twice on the same object错误
方案1:让每个子类独立维护单例实例
修改父类的单例逻辑,用Map存储不同子类的实例,确保每个子类都有自己的单例:
class A{ static #instances = new Map() #a = 1 constructor(){ const Constructor = this.constructor; if(!A.#instances.has(Constructor)){ A.#instances.set(Constructor, this) } return A.#instances.get(Constructor) } } class B extends A{ #b = 2 } // 测试验证:两次new B()返回同一个实例 console.log(new B() === new B()); // true
方案2:仅限制父类为单例,子类正常实例化
如果只需要父类A保持单例,子类B可以自由创建实例,调整父类逻辑如下:
class A{ static #instance = null #a = 1 constructor(){ if(this.constructor === A){ if(!A.#instance){ A.#instance = this } return A.#instance } // 子类实例化时不干预,直接返回当前实例 } } class B extends A{ #b = 2 } // 测试验证:父类保持单例,子类每次实例化都返回新对象 console.log(new A() === new A()); // true console.log(new B() === new B()); // false
内容的提问来源于stack exchange,提问作者user19685881
相关产品推荐
相关产品推荐

