In the following code I have an unexpected behaviour for me. I was waited to see the method A2::method() to be called, but it is A0::method() instead. More tests showed me that if A1 returns something, it will keep public prop from A2 but forget all methods from A2. Maybe I'm doing something wrong. Is there a workaround
class A0 {
method() {
return "from A0 " + this.prop
}
}
class A1 {
constructor() {
return new A0;
}
}
class A2 extends A1 {
constructor(v) {
super()
console.log('here')
this.prop = v;
}
prop = 42;
method() {
return "from A2 " + this.prop
}
}
const a = new A2(42);
console.log(a.prop, a.method())
Result
[LOG]: "here"
[LOG]: 42, "from A0 42"
Expected
[LOG]: "here"
[LOG]: 42, "from A2 42"
As the documentation says:
The constructor method may have a return value. While the base class may return anything from its constructor, the derived class must return an object or undefined, or a TypeError will be thrown. If the parent class constructor returns an object, that object will be used as the this value on which class fields of the derived class will be defined. This trick is called "return overriding", which allows a derived class's fields (including private ones) to be defined on unrelated objects.
In your example, the object you have created is not an actual instance of A1
or A2
class A0 {
method() {
return "from A0 " + this.prop
}
}
class A1 {
constructor() {
return new A0;
}
}
class A2 extends A1 {
constructor(v) {
super()
console.log('here')
this.prop = v;
}
prop = 42;
method() {
return "from A2 " + this.prop
}
}
const a = new A2(42);
console.log(a.prop, a.method());
console.log('Is a instance of A0:', a instanceof A0); // true
console.log('Is a instance of A1:', a instanceof A1); // false
console.log('Is a instance of A2:', a instanceof A2); // false
In other terms, you have created an object that does not have A1
or A2
in its prototype chain, but the A2
constructor still attached prop
to it.