Considering the following code
class A {
a;
constructor() { console.log(2); this.inv(); }
inv() { console.log(4); this.a = "a value"; }
}
class B extends A {
b;
constructor() { console.log(1); super(); }
inv() {
console.log(3);
super.inv();
console.log(5);
this.b = "b value";
console.log(this.b);
console.log(this.constructor === B);
}
}
const b = new B();
console.log(b.a);
console.log(b.b);
I get the following output:
1
2
3
4
5
b value
true
a value
undefined
I would expect b.b
to be b value
. How come b.b
is undefined
? How can I achieve what I’m trying to do?
2
Answers
Well that is because when you’re doing
const b = new B();
, you’re starting off with a fresh instance ofB
, which does not have any defined value (yourb
property isn’t initialized). Since you have not set a value forb
again for this fresh instance ofB
, it will show up asundefined
.You are setting
b
tob value
inB.inv()
. So you’ll need to callb.inv()
before you printb.b
or you can pass theb
in the constructor. Something likeThis would ensure the
b
value is assigned during object creation.Also, as noted before, this pattern you’re following isn’t ideal. Your
super()
call initializesb
to "b value" in theb.inv()
method (which gets invoked viasuper()
->this.inv()
) . In Class A,this.inv()
actually callsB.inv()
via method overriding. However, once this call is done, and we exit out of the originalsuper()
call in theB
constructor,this.b
gets defaulted to undefined. Placing an explicitthis.b = b
remedies this.b;
Is setting value toundefined
after the constructor proceeded. While Bergi comment is surely the best move (try not to nest, prefer composition over inheritance etc.) if you like it quick and dirty, you actually don’t need to declare properties in JS and so you would actually get your expected output by just removingb;
: