3

I am trying to override one method from the parent class, but there are some issues.

Below is the code snippet of my scenario which I am trying.

class Parent {
add = () => {
      console.log('Parent method');
}
}
class Child extends Parent {
add () {
console.log('Child Method');
 }
}
// Creating an instance
const child = new Child();
child.add();

It is calling the Parent method add as that is arrow function, Can someone explain why this is happening. If I make the parent function a simple javascript method then child is able to override.

Additonal Details :

  1. I don't have access to Parent as it is part of library.
  2. I can't make my child class method as instance properties (arrow function) , the reason for being that there are further specification written for child (child of child) and If we use arrow functions we will not be able to call the super.
  3. Child function name can't be renamed.
Mohit Sharma
  • 340
  • 2
  • 11

2 Answers2

3

This is one of few reasons why arrow methods aren't convenient. They limit the ways in which a class can be extended and tested.

Class fields (which arrow methods are) are syntactic sugar for constructor code:

class Parent {
  constructor() {
    this.add = () => {...};
  }
}

Only another arrow method can override parent arrow method, because they are defined in class constructor, not on class prototype:

class Child extends Parent {
  add = () => {
    /* no super.add here because add is not prototype method */
  }
}

If super.add is intended to be used, a workaround is to store parent method:

class Child extends Parent {
  superAdd = this.add;
  add = () => {
    this.superAdd();
  }
}

Notice that since this is syntactic sugar for constructor code, the order in which superAdd and add are defined matters.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
2

The parent add is an instance property, and it overshadows the child's class method, which is part of the instance's prototype. It's a bit hacking, but you can rename and delete the class property in the constructor:

class Parent {
  add = () => {
    console.log('Parent method');
  }
}
class Child extends Parent {
  constructor() {
    super();
    this.parentAdd = this.add;
    delete this.add;
  }

  add() {
    console.log('Child Method');
    this.parentAdd(); // if you need call the parent's method
  }
}

const child = new Child();
child.add();
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
  • I don't have access to Parent as it is part of library. I can't make my child class method as instance properties (arrow function) , the reason for being that there are further specification written for child (child of child) and If we use arrow functions we will not be able to call the super. – Mohit Sharma Jul 18 '18 at 11:26
  • @MohitSharma Consider updating the question with all relevant details. If you can't change Parent, specify it. If you want to call super in child class, this should be mentioned, too. – Estus Flask Jul 18 '18 at 11:30