Note: this is not a duplicate. The question linked below asks simply about class variables, and not specifically about a workaround to allow inheritance. I apply the answers in that question to a potential inheritance solution, without success.
What I need to do: basic property overrides:
class ProductA {
weight: 5,
height: 10,
price: 7
}
class ProductB extends ProductA {
height: 12
}
class ProductC extends ProductA {
price: 12,
weight: 2
}
class ProductC2 extends ProductC {
height: 5
}
We can't do this with ES2015???
According to this question, properties aren't supported in ES2015. Those answers recommend:
Use the constructor?
class ProductA {
constructor(){
this.weight = 5;
this.height = 10;
this.price = 7;
}
}
// and then...?
class ProductB extends ProductA {
constructor(){
super()
this.height = 12;
}
}
That might appear to work, until you want to add this.initialize()
call in ProductA's constructor, for example... There's an ES2015 rule that says you have to call super()
before anything else. For ProductB, you'd have to call super()
before overriding the properties, which would be the wrong order (considering your initialize()
logic uses those properties).
Use getters to map properties to the Class object?
class ProductA {
get weight() {
return this.constructor.weight;
}
}
ProductA.weight = 5;
// also for height, price, and all other properties...?
I'm surprised this even works: when you extend the class, the getter somehow maps back to the base class, unless its own constructor has the property. It's almost like ProductB's prototype is ProductA.
The big problem here is to allow instance-level overrides (this.weight = 6
). You'd have to add a setter method, and modify the getter to look at this.weight
or fall back to this.constructor.weight
. That's basically reimplementing simple inheritance. Why?!
This page has a better solution:
class ProductA {
constructor(options) {
Object.assign(this, {
weight: 5,
height: 10,
price: 7
}, options);
}
}
class ProductB extends ProductA {
constructor(options){
super(Object.assign({
height: 12
}, options));
}
}
There's still the problem of having to use "super()", which prevents me from overriding properties before running the init logic.
I was able to do this really easily in ES5. There has to be a better implementation or workaround?