Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript classes : how to access overridden parent class functions in parent class code

Javascript ES6 ( node 8.4.0 and latest chrome and recent Firefox )

I expected

class Parent {
    init(){
        console.log("Parent init") ;
        this._surname = "McClass" ;
    }
    constructor() {
        console.log("Parent constructor") ;
        this.init();
    }

    get surname(){
        return this._surname ;
    }
}

class Child extends Parent {

    init(){
        console.log("Child init") ;
    }
    constructor() {
        super();
        console.log("Child constructor") ;
        this.init();
    }    
}

var child = new Child() ;

console.log(child.surname);

to give the following output;

Parent constructor
Parent init
Child constructor
Child init
McClass

(which is what comparable C++ code gives)

Alas, I got this ;

Parent constructor
Child init
Child constructor
Child init
undefined

Am I doing something wrong or is this the correct intended behaviour and if so how is it justified ?

EDIT;

See MinusFour's answer below on how to achieve what I was trying to do / expecting.

As to why the observed output is the "correct" behaviour and justified ;

As Bergi pointed out (in comments) all calls to object methods in js are effectively "virtual" (the last method of that name added to the object's prototype inheritance chain being the first found and hence executed). It turns out calls are still effectively virtual in a class construction context.

C++ does not apply virtual method behaviour during construction but then again Java does and you get the same output (as above) in comparable Java code so there is a precedent for the observed behaviour.

like image 773
Bob Avatar asked Sep 06 '25 03:09

Bob


1 Answers

You could do:

Parent.prototype.init.call(this);

class Parent {
  init() {
    console.log("Parent init");
    this._surname = "McClass";
  }
  constructor() {
    console.log("Parent constructor");
    Parent.prototype.init.call(this);
  }

  get surname() {
    return this._surname;
  }
}

class Child extends Parent {

  init() {
    console.log("Child init");
  }
  constructor() {
    super();
    console.log("Child constructor");
    this.init();
  }
}

var child = new Child();

To make sure it never gets overridden, but I would suggest you just not override it in the first place.

like image 134
MinusFour Avatar answered Sep 07 '25 21:09

MinusFour