I use polymorphism with JSDoc to describe concrete implementations of some classes. Up until now I have been doing this with getters and setters; newly implemented public class fields can shorten this getter and setter boilerplate considerably.
My problem is described by the code snippet below. The value set in the constructor does not survive the redefining of the public class field. How can I redefine a public class field in an inheriting class and keep the value set in the super constructor? Is this a bug in public class fields?
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)
Edit: This question was not about my motivations. Why do public fields behave differently to getters with regard to the prototype chain?
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