Home > Mobile >  What is the order of executing super() constructor and subclass methods in javascript object oriente
What is the order of executing super() constructor and subclass methods in javascript object oriente

Time:12-09

Why is this undefined in render() method inside of the subclass? Why this inside of the base class constructor refers to the created object based on subclass? I want to know the execution order in here.

class baseClass {
    constructor() {
        this.render(); // why does "this" (not this.render()) refer to the created object based on derivedClass?
    }

    render() {
        console.log("won't get executed.");
    }
}

class derivedClass extends baseClass {
    foo = "foo"
    constructor() {
        super();
        console.log(this); 
    }

    render() {
        console.log(this.foo); // why is "this" undefined?
        alert("rendered");
    }
}

new derivedClass;

CodePudding user response:

To better understand how it works you can change your code a bit:

class baseClass {
  bar = 'bar';

  constructor() {
    console.log(
      `In baseClass constructor this is ${JSON.stringify(this, null, 2)}`
    );
    this.render(); // why does "this" (not this.render()) refer to the created object based on derivedClass?
  }

  render() {
    console.group();
    console.log(this);
    console.log('baseClass rendered');
    console.groupEnd();
  }
}

class derivedClass extends baseClass {
  foo = 'foo';
  constructor() {
    super();
    console.log(
      `In derivedClass constructor this is ${JSON.stringify(this, null, 2)}`
    );
    this.render();
  }

  render() {
    console.group();
    console.log(this);
    console.log('derivedClass rendered');
    console.groupEnd();
  }
}

new derivedClass();

It will output:

In baseClass constructor this is {
  "bar": "bar"
}
  derivedClass { bar: 'bar' }
  derivedClass rendered
In derivedClass constructor this is {
  "bar": "bar",
  "foo": "foo"
}
  derivedClass { bar: 'bar', foo: 'foo' }
  derivedClass rendered

So the sequence is as follows:

  1. derivedClass constructor is called when you do new derivedClass();
  2. It calls the baseClass constructor
  3. The data members are populated with what baseClass "owns"
  4. The methods though are of derivedClass, that's why you see "derivedClass rendered" when render is called from the baseClass constructor.
  5. The data members of derivedClass are added
  6. derivedClass constructor calls render again.

It is somewhat counter-intuitive, especially if you come from OOP background with C , Java, etc. And I think this is the reason why some try to avoid classes and this in JavaScript entirely.

  • Related