Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 334
Max Avatar asked Dec 18 '18 11:12

Max


People also ask

Is ES6 just syntactic sugar?

ES6 as Syntactic Sugar Which simply means its the same features in a more accessible way to developers instead of computers, which seems a good thing as in programming languages we as developers want the syntax friendly, accessible, concise and expressive by itself.

Which JavaScript feature is the alternative to the ES6 classes the class keyword )?

In the ES6 way, The function keyword is replaced with the class keyword. There's a special function named 'constructor' where the initialization of the object is done. Hence whatever is present in the body of the traditional function gets shifted to the 'constructor' function.

Will ES6 classes bind the instance automatically?

[React Component Class] Methods follow the same semantics as regular ES6 classes, meaning that they don't automatically bind this to the instance.


1 Answers

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)

like image 145
CertainPerformance Avatar answered Oct 17 '22 06:10

CertainPerformance