Max
Max

Reputation: 91

JavaScript override from a non ES6 class to an ES6 class

In my Webapp I need to implement an API, which does not contain any ES6 class definitions, but I would like to extend of one of these classes and override some methods. Overriding does not work properly...

function A() {
  this.msg = function() {
    console.log("A");
  }
}

class B {
  constructor() {
    A.call(this);
  }

  msg() {
    console.log("B");
  }
}

new B().msg();

I expect "B" as result but the method of "class" A gets executed.

Upvotes: 7

Views: 452

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370689

The problem is that in A, the msg function is attached to this in the constructor - that is, the msg property is attached directly to the instance object itself, not on the prototype. In contrast, the msg of B is on the prototype of B - that is, B.prototype, the object that the instance inherits from.

One option would be to overwrite msg in B's constructor:

function A() {
  this.msg = function() {
    console.log("A");
  }
}

class B {
  constructor() {
    A.call(this);
    this.msg = () => {
      console.log('b');
    }
  }
}

new B().msg();

A nicer looking prototypal solution would be for B to extend A, if that's a possible modification you can make:

function A() {
  // empty constructor
}
A.prototype.msg = function() {
  console.log("A");
}

class B extends A {
  msg() {
    console.log('b');
  }
}

new B().msg();

(with this, the internal prototype chain looks like: A.prototype -> B.prototype -> instance, so from the instance, B.prototype.msg takes priority over A.prototype.msg)

Upvotes: 4

Related Questions