Mohamed Abo El Soud
Mohamed Abo El Soud

Reputation: 56

JS inheritence overriding in constructor?

can someone explain the following to me?

class BaseClass {
  prop = 88;
  constructor(){
    console.log("baseClass prop is ", this.prop);
  }
}
class DerivedClass extends BaseClass{
  prop = 83;
  constructor(){
    super();
    console.log("derivedClass prop is ", this.prop);
  }
}
new derivedClass();

and the output is

baseClass prop is  88
derivedClass prop is  83

now shouldn't both props be the same (83)? because one prop overridden the other? Am i getting something wrong here?

Upvotes: 3

Views: 191

Answers (3)

shotor
shotor

Reputation: 1062

You are forgetting about the super() call in the constructor of your derived class.

What this does is call the constructor of the base class. So the constructor of the base class is run to completion prior to the constructor of the derived class.

Meaning when the console.log statement of the base class is executed, the prop variable is still 88.

Upvotes: 4

Badacadabra
Badacadabra

Reputation: 8507

Your code is invalid. ES6 is not TypeScript, so your class attributes must be declared inside your constructors. Moreover, you should follow a coding convention that favors pascal case over camel case for class names. Here is the correct syntax:

class BaseClass {
  constructor(){
    this.prop = 88;
    console.log("BaseClass prop is", this.prop);
  }
}
    
class DerivedClass extends BaseClass {
  constructor(){
    super();
    this.prop = 83;
    console.log("DerivedClass prop is", this.prop);
  }
}
    
new DerivedClass();

So, why do we have 88 and 83? In fact, when your derived class calls the base class via super(), this.prop is 88 and you log it immediately. When super() execution ends, this.prop becomes 83, but there is no reason for your previous log to disappear...

Now, if you want private attributes for some reasons, you could declare them outside your constructors, but you would need IIFEs (Immediately-Invoked Function Expressions):

const BaseClass = (() => {
  let prop = 88;

  class BaseClass {
    constructor(){
      console.log("BaseClass prop is", prop);
    }
  }

  return BaseClass;
})();
 
const DerivedClass = (() => {
  let prop = 83;
    
  class DerivedClass extends BaseClass {
    constructor(){
      super();
      console.log("DerivedClass prop is", prop);
    }
  }
  
  return DerivedClass;
})();
    
new DerivedClass();

As you can see, each class uses the prop variable defined in its own scope.

Upvotes: 0

loganfsmyth
loganfsmyth

Reputation: 161627

Class properties are initialized on construction from the bottom of the class heirarchy up, as the constructors are executed.

  • On base classes, they initialized inside the constructor automatically at the start.
  • On subclasses, they run immediately after super().

The logic is essentially

this.prop = 88;
console.log("baseClass prop is ", this.prop);

this.prop = 83;
console.log("derivedClass prop is ", this.prop);

because the class are

class BaseClass {
  constructor(){
    this.prop = 88;
    console.log("baseClass prop is ", this.prop);
  }
}

class DerivedClass extends BaseClass {
  constructor(){
    super();
    this.prop = 83;
    console.log("derivedClass prop is ", this.prop);
  }
}

Upvotes: 2

Related Questions