gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 05:59:51 25 4
gpt4 key购买 nike

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

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

class ThingHolder {
/**@type {notKnownYet}*/
publicFieldForThing
constructor(thing) {
this.publicFieldForThing = thing
//Do stuff for all thing holders
}
dropMyThing() {
//Throw not implemented
}
setThingField(thing) {
this.publicFieldForThing = thing
}
}

class RedThingHolder extends ThingHolder {
/**@type {RedThing}*/
publicFieldForThing
dropMyThing() {
//functionality for dropping a red thing with JSDoc niceties for RedThings
}
}
class BlueThingHolder extends ThingHolder {
/**@type {BlueThing}*/
publicFieldForThing
dropMyThing() {
//functionality for dropping a blue thing with JSDoc niceties for BlueThings
}
}

const redThing = {
colour: "red"
}

//Setting the thing in the constructor results in unextected behaviour
const redThingHolder = new RedThingHolder(redThing)
console.assert(redThingHolder.publicFieldForThing === redThing)

//Setting the thing through an inherited method after construction works perfectly fine
redThingHolder.setThingField(redThing)
console.assert(redThingHolder.publicFieldForThing === redThing)

编辑:这个问题与我的动机无关。为什么公共(public)字段在原型(prototype)链方面与 getter 的行为不同?

class Parent {
constructor() {
console.log("prop in instance during super: ", "prop" in this)
console.log("publicField in instance during super: ", "publicField" in this)
}
}

class Child extends Parent {
constructor() {
super()
console.log("prop in instance after super: ", "prop" in this)
console.log("publicField in instance after super: ", "publicField" in this)
}
publicField
get prop() { }
}

new Child

最佳答案

当你调用RedThingHolder类的构造函数时

new RedThingHolder(redThing)

RedThingHolder 的默认构造函数会将参数 redThing 传递给父类(super class)的构造函数,该构造函数会在新创建的对象上添加一个属性 publicFieldForThing对象。

在子类中重新定义 publicFieldForThing 覆盖在父类(super class)中设置的 publicFieldForThing

I feel like this is a bug and that the value should be retainedautomatically.

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

这样做

class RedThingHolder {
publicFieldForThing;
...
}

将用 undefined 的默认值覆盖 publicFieldForThing 字段。

How can I redefine a public class field in an inheriting class andkeep the value set in the super constructor?

您可以使用父类(super class)中定义的 publicFieldForThing 的 getter 在子类构造函数中设置 publicFieldForThing

class ThingHolder {
constructor(thing) {
this.publicFieldForThing = thing;
}

get publicField() {
return this.publicFieldForThing;
}
}

class RedThingHolder extends ThingHolder {
constructor(thing) {
super(thing);
this.publicFieldForThing = this.publicField;
}
}

const redThing = {
colour: 'red',
};

const redThingHolder = new RedThingHolder(redThing);
console.log(redThingHolder.publicFieldForThing === redThing);

编辑

Why do public fields behave differently to getters with regard to theprototype chain?

ES2015 类中的 getter/setter 被添加到原型(prototype)对象上,而公共(public)字段被添加到对象本身。

在您发布的代码示例中,prop 被添加到 Child.prototypepublicField 就像在做

this.publicField = undefined;

Child 类的构造函数中, super() 调用之后。

这就是为什么 Parent 类的构造函数中的 "prop"in this 返回 true"publicField"在此 仅在 Child 类的构造函数内部评估为 true

关于javascript - 如果在继承类中重新定义该字段,则无法从 super 的构造函数设置公共(public)类字段的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67931433/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com