Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to invoke arrow functions on a superclass with `super` in subclass [duplicate]

It seems you cannot call a superclass arrow function using super.methodName() within a subclass:

class Parent {
  constructor() {
    console.log('in `Parent` constructor')
  }
  parentArrow = () => {
    console.log('parentArrowFn')
  }
  parentMethod() {
    console.log('parentMethod')
  }
}

class Child extends Parent {
  constructor() {
    super()
    console.log('in `Child` constructor')
  }
  childMethod() {
    console.log('childMethod')
    super.parentMethod() // works
    super.parentArrow() // Error
  }
}

(new Child()).childMethod();

Generates the error:

Uncaught TypeError: (intermediate value).parentArrow is not a function
    at Child.childMethod (<anonymous>:21:15)
    at <anonymous>:1:7

Is there any way to prevent this so that I can use arrow functions in my parent class, yet ensure they are accessible via super in subclasses?

like image 282
1252748 Avatar asked Sep 16 '25 23:09

1252748


1 Answers

Public fields or "class instance fields" in es6 classes are not yet supported natively in all environments and even if it is you need to call it through a this reference instead of super as it becomes an instance property rather than a property on the prototype:

class Parent {
  constructor() {
    console.log('in `Parent` constructor')
  }   
  parentArrow = () => {
      console.log('parentArrowFn')
  }
  parentMethod() {
    console.log('parentMethod')
  }
}

class Child extends Parent {
  constructor() {
    super()
    console.log('in `Child` constructor')
  }
  childMethod() {
    console.log('childMethod')
    super.parentMethod() // works
    this.parentArrow() // Calls parentArrow 
  } 
}
new Child().childMethod();

The need to call the arrow function using this instead of super is because when using an arrow function as a method the parentArrow is added as a property of the instance rather than of the prototype and super is used for calling methods declared on the prototype.

Your code can be translated to the code below, when you declare an arrow function inside a class:

constructor() {
   console.log('in `Parent` constructor');
   // becomes an instance property
   this.parentArrow = () => { <----
     console.log('parentArrowFn') |
   }                              |
}                                 |
parentArrow = () => {          ----
   console.log('parentArrowFn')
}
like image 137
Fullstack Guy Avatar answered Sep 18 '25 13:09

Fullstack Guy