So I'm curious if it's possible from a base (parent) class to access static properties from all levels in a class hierarchy.
Let's paint an example:
class Tier1 {
static NUMBERS = ['one', 'two'];
getNumbers() {
// how to do here?
return this.constructor.NUMBERS.join(', ');
}
}
class Tier2 extends Tier1 {
static NUMBERS = ['three'];
}
class Tier3 extends Tier2 {
static NUMBERS = ['four', 'five'];
}
class Tier4 extends Tier3 {
static NUMBERS = ['six'];
}
const t1 = new Tier1(); t1.getNumbers(); // Expect to get "one, two"
const t2 = new Tier2(); t2.getNumbers(); // Expect to get "one, two, three"
const t3 = new Tier3(); t3.getNumbers(); // Expect to get "one, two, three, four, five"
const t4 = new Tier4(); t4.getNumbers(); // Expect to get "one, two, three, four, five, six"
Is it possible to achieve this effect? Can I traverse down the class instance hierarchy from this
in a dynamic way?
Would love some input and ideas here
You can do it by creating a new static NUMBERS variable at each level that is a copy of the previous one and adding the new items, as follows:
class Tier1 {
static NUMBERS = ['one', 'two'];
getNumbers() {
return this.constructor.NUMBERS.join(', ');
}
}
class Tier2 extends Tier1 {
static NUMBERS = [...this.NUMBERS, 'three'];
}
class Tier3 extends Tier2 {
static NUMBERS = [...this.NUMBERS, 'four', 'five'];
}
class Tier4 extends Tier3 {
static NUMBERS = [...this.NUMBERS, 'six'];
}
const t1 = new Tier1(); console.log(t1.getNumbers()); // Shows "one, two"
const t2 = new Tier2(); console.log(t2.getNumbers()); // Shows "one, two, three"
const t3 = new Tier3(); console.log(t3.getNumbers()); // Shows "one, two, three, four, five"
const t4 = new Tier4(); console.log(t4.getNumbers()); // Shows "one, two, three, four, five, six"
Or if you need to have a separate NUMBERS array in each class, and combine them as late as possible (e.g. because their contents could be mutable), then you can follow the approach below. I think this also answers "Can I traverse down the class instance hierarchy from this
in a dynamic way?" with a definite "yes".
class Tier1 {
static NUMBERS = ['one', 'two'];
gatherAllNumbers() {
const constructors = this.getConstructors();
return constructors.reverse().map(c => c.NUMBERS).flat();
}
getConstructors() {
const result = [];
let next = Object.getPrototypeOf(this);
while (next.constructor.name !== "Object")
{
result.push(next.constructor);
next = Object.getPrototypeOf(next);
}
return result;
}
getNumbers() {
return this.gatherAllNumbers().join(', ');
}
}
class Tier2 extends Tier1 {
static NUMBERS = ['three'];
}
class Tier3 extends Tier2 {
static NUMBERS = ['four', 'five'];
}
class Tier4 extends Tier3 {
static NUMBERS = ['six'];
}
const t1 = new Tier1(); console.log(t1.getNumbers()); // Shows "one, two"
const t2 = new Tier2(); console.log(t2.getNumbers()); // Shows "one, two, three"
const t3 = new Tier3(); console.log(t3.getNumbers()); // Shows "one, two, three, four, five"
const t4 = new Tier4(); console.log(t4.getNumbers()); // Shows "one, two, three, four, five, six"