Javascript 如果在继承类中重新定义了公共类字段,则无法从super的构造函数中设置该字段的值

Javascript 如果在继承类中重新定义了公共类字段,则无法从super的构造函数中设置该字段的值,javascript,Javascript,我使用多态性和JSDoc来描述一些类的具体实现。到目前为止,我一直在做这件事,与能手和二传手;新实现的可以大大缩短这个getter和setter样板 下面的代码片段描述了我的问题。构造函数中设置的值在重新定义公共类字段后无法继续存在。如何在继承类中重新定义公共类字段并在超级构造函数中保留值集?这是公共类字段中的错误吗 class ThingHolder{ /**@类型{notKnownYet}*/ 公共领域 构造器(东西){ this.publicFieldForThing=事物 //为所有人

我使用多态性和JSDoc来描述一些类的具体实现。到目前为止,我一直在做这件事,与能手和二传手;新实现的可以大大缩短这个getter和setter样板

下面的代码片段描述了我的问题。构造函数中设置的值在重新定义公共类字段后无法继续存在。如何在继承类中重新定义公共类字段并在超级构造函数中保留值集?这是公共类字段中的错误吗

class ThingHolder{
/**@类型{notKnownYet}*/
公共领域
构造器(东西){
this.publicFieldForThing=事物
//为所有人做事
}
丢弃神话(){
//抛出未实现
}
setThingField(东西){
this.publicFieldForThing=事物
}
}
类RedThingHolder扩展了ThingHolder{
/**@类型{RedThing}*/
公共领域
丢弃神话(){
//用于删除红色对象的功能,具有针对红色对象的JSDoc细节
}
}
类BlueThingHolder扩展了ThingHolder{
/**@类型{BlueThing}*/
公共领域
丢弃神话(){
//使用JSDoc的BlueThings细节删除蓝色物件的功能
}
}
常数redThing={
颜色:“红色”
}
//在构造函数中设置对象会导致未检测的行为
const redThingHolder=新的redThingHolder(redThing)
assert(redThingHolder.publicFieldForThing===redThing)
//在建筑完成后,通过继承的方法进行设置,效果非常好
redThingHolder.setThingField(redThing)

调用
redThingHolder
类的构造函数时,断言(redThingHolder.publicFieldForThing===redThing)

new RedThingHolder(redThing)
RedThingHolder
的默认构造函数将参数
redThing
传递给超级类的构造函数,该构造函数将在新创建的对象上添加属性
publicFieldForThing

在子类中重新定义
publicFieldForThing
,将覆盖超类中设置的
publicFieldForThing

我觉得这是一个bug,应该保留这个值 自动地

这不是一个bug,重新定义具有相同名称的属性不会保留值,因为您定义的字段的名称已经存在于对象上。它将覆盖现有字段,而不是保留

这样做

class RedThingHolder {
   publicFieldForThing;
   ...
}
将用默认值
undefined
覆盖
publicFieldForThing
字段

如何在继承类中重新定义公共类字段 是否在超级构造函数中保留设置的值

您可以使用超类中定义的
publicFieldForThing
的getter在子类构造函数中设置
publicFieldForThing

class ThingHolder{
构造器(东西){
this.publicFieldForThing=事物;
}
获取公共字段(){
返回此.publicFieldForThing;
}
}
类RedThingHolder扩展了ThingHolder{
构造器(东西){
超级(东西);
this.publicFieldForThing=this.publicField;
}
}
常数redThing={
颜色:“红色”,
};
const redThingHolder=新的redThingHolder(redThing);

console.log(redThingHolder.publicFieldForThing==redThing)为什么需要在子类中重新定义属性?有几个原因,但最重要的原因是上面的注释;开发人员将一个记录良好的类传递给团队的其他成员时的体验。红色和蓝色的东西都有非常不同的属性和方法。你称之为改进DX,我认为你违反了DRY。如果您不想使用继承,请不要使用继承。只需将所有共享实现作为独立功能或其他东西提供即可?“开发者体验”-我不确定重新定义字段如何改善开发人员体验,而不是混淆他们。请参见答案末尾的编辑。您删除了在重新定义字段上键入的JSDoc,这违背了问题的全部目的。我不同意,如果是在子类中重新定义的getter和setter,在构造函数中设置属性实际上会调用重新定义的setter。超级构造函数中的“this”是子构造函数的实例。超级构造函数中的“this”是子构造函数的实例。让我重新表述我已删除的最后一条评论。超级类中的构造函数将在新创建的实例上设置
publicFieldForThing
。在超级类构造函数执行之后,创建并初始化了一个对象。在子类中,重新定义字段将不会保留该值-相反,它将隐藏/覆盖超类中已添加的字段。