skip to Main Content

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


  1. Well that is because when you’re doing const b = new B();, you’re starting off with a fresh instance of B, which does not have any defined value (your b property isn’t initialized). Since you have not set a value for b again for this fresh instance of B, it will show up as undefined.

    You are setting b to b value in B.inv(). So you’ll need to call b.inv() before you print b.b or you can pass the b in the constructor. Something like

    class B extends A {
        b;
    
        constructor(b) { console.log(1); super(); this.b = b; }
    

    This 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 initializes b to "b value" in the b.inv() method (which gets invoked via super() -> this.inv()) . In Class A, this.inv() actually calls B.inv() via method overriding. However, once this call is done, and we exit out of the original super() call in the B constructor, this.b gets defaulted to undefined. Placing an explicit this.b = b remedies this.

    Login or Signup to reply.
  2. b; Is setting value to undefined 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 removing b;:

    class A {
        a;
    
        constructor() { console.log(2); this.inv(); }
    
        inv() { console.log(4); this.a = "a value"; }
    }
    
    class B extends A {
        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);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search