0
class Base {
    constructor() {
        console.log(this); /*break point here in chrome debugger*/
    }
}

class Derived extends Base {
    constructor() {
        super();
    }
}

new Derived(); Why value of [this] = Derived in the Local Scope inside the constructor of the Base class?

new Base(); The value of [this] = Base in the Local Scope as I was expecting.

Snm Jpa
  • 71
  • 1
  • 4
  • 1
    See [How does the “this” keyword work?](/q/3127429/4642212). It explains everything. `super()` calls the `constructor` of `Base` with `this` set to the `Derived` instance. `this` is neither `Base` nor `Derived` in both of your examples. – Sebastian Simon Aug 21 '21 at 16:38
  • @SebastianSimon So after calling `super()` in the `Derived` class, in the `Base` class constructor we've the code evaluation similar to this? `class Base { constructor() { this = new Derived(); }}` ? – Snm Jpa Aug 21 '21 at 16:54
  • 1
    Kind of… the instantiation already happens at the original `new Derived();`. You can imagine the `super` call like an implicit `super(this);` and `class Base { constructor(thisRef){ console.log(thisRef); } }`. Or, in the older prototypal pattern (if you’re familiar with it), `super()` works like `Base.call(this)`, passing `this` (the instance of `Derived`) to `Base`, where it also will be usable as `this`. – Sebastian Simon Aug 21 '21 at 16:59
  • `super(this)` This is helping me to visualize. Thanks – Snm Jpa Aug 21 '21 at 17:03
  • @SebastianSimon - *"... the instantiation already happens at the original new Derived()..."* Not with JavaScript's `class` syntax. The instantiation doesn't happen until the base class constructor is reached. (This is different from the way it worked with chained constructors in ES5 and earlier.) It's literally the base class constructor that creates the instance (using the `new.target` it was passed through the chain). (This is part of why `this` can't be used before `super`.) – T.J. Crowder Aug 21 '21 at 18:39

1 Answers1

2

this isn't either Base or Derived in your examples. It's an instance of Base and (where you use new Derived) also an instance of Derived.

When you do new Derived, this is created as an instance of Derived. It doesn't matter whether you look at it in the Base constructor or the Derived constructor, in both cases this refers to the single object created by using new (which is an instance of both Base and Derived).

Here's some other logging that may be more useful:

class Base {
    constructor() {
        console.log(
            "In Base:   ",
            this instanceof Base,
            this instanceof Derived,
            this.constructor.name
        );
    }
}

class Derived extends Base {
    constructor() {
        super();
        console.log(
            "In Derived:",
            this instanceof Base,
            this instanceof Derived,
            this.constructor.name
        );
    }
}

new Derived();
// =>
// In Base:    true true Derived
// In Derived: true true Derived

We can go further to prove it's the same object (you wouldn't store the value of this on a global variable in real code, but this is to see what's going on in this specific example):

let thisInBase;
class Base {
    constructor() {
        thisInBase = this;
        console.log(
            "In Base:   ",
            this instanceof Base,
            this instanceof Derived,
            this.constructor.name
        );
    }
}

let thisInDerived;
class Derived extends Base {
    constructor() {
        super();
        thisInDerived = this;
        console.log(
            "In Derived:",
            this instanceof Base,
            this instanceof Derived,
            this.constructor.name
        );
    }
}

const instance = new Derived();
// =>
// In Base:    true true Derived
// In Derived: true true Derived
console.log(instance === thisInBase);
// => true
console.log(instance === thisInDerived);
// => true
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I would nitpick that `this` is not an instance of `base` and also `Derived`. It is an instance of one or the other (even if instances of `Derived` also implement `base`). – Jonathan Wood Aug 21 '21 at 17:01
  • Great answer to the post! helped me to understand in one go. – Snm Jpa Aug 21 '21 at 17:08
  • @JonathanWood - Instances of subtypes *are* instances of supertypes, that's fundamental to inheritance. – T.J. Crowder Aug 21 '21 at 18:38