So apparently this is an order-of-operations issue.
Execution order:
Son
implied constructor is called
- ... which calls
super()
or Dad constructor
Son.init()
is called
this.foo
is set to 'bar'
(Dad
constructor finished)
- After
super()
constructor is finished, the child Son
class apparently sets properties defined in the Son
class scope to their defaults, in this case foo;
or foo = undefined;
I don't like it, but one solution is to remove foo;
from the Son
class definition. Apparently VS Code intellisense will still pick up on the foo
property even if it's not defined in the class definition or constructor, which is one of the goals. As far as readability goes, it's slightly worse not to have foo
in the class definition or constructor.
Another solution:
class Dad {
// To be called after super() in child constructors
// Class field initializers overwrite assignments made by super(), so
// anything set here could be overwritten if it were in the constructor
callMeAfterSuper() {
this.init();
}
init() {}
}
class Son extends Dad {
foo;
constructor() {
super();
super.callMeAfterSuper();
}
init() {
this.foo = 'bar';
console.log('init', this.foo);
}
}
let son = new Son();
console.log('son', son.foo);