Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES6 Javascript: Calling static methods from classes with arrow functions

While this works as intended

class ClassWithStaticMethod {

  static staticMethod() {
    return ('staticMethod');
  };

  static staticMethod2() {
    const yee = this.staticMethod();
    return 'staticMethod2 '+yee;
  };

}

console.log(ClassWithStaticMethod.staticMethod2());
//staticMethod2 staticMethod

This is,

i) have access to the staticMethod() with the class name, and

ii) this method can call another static method within the same class by using "this",

This doesn't work

class ClassWithStaticMethod {

  static staticMethod = () => {
    return ('staticMethod');
  };

  static staticMethod2 = () => {
    const yee = this.staticMethod;
    return 'staticMethod2 '+yee;
  };

}

console.log(ClassWithStaticMethod.staticMethod2());
//staticMethod2 undefined

In the sense, that I can still access to the staticMethod() method, but I am not able to access to the other method within the first method. I get undefined, and if I use

    const yee = this.staticMethod();

I get an error

error TypeError: _this.staticMethod is not a function

like image 615
GWorking Avatar asked Sep 11 '18 05:09

GWorking


2 Answers

Arrow functions inherit their this from the outer scope rather than their this depending on their calling context. Since staticMethod2 tries to access this.staticMethod, that will only work if this refers to ClassWithStaticMethod - that is, if staticMethod2 is a standard function, not an arrow function.

You also need to invoke this.staticMethod(). (const yee = this.staticMethod; will result in the staticMethod being coerced to a string, rather than being called)

Change those two issues, and it works as expected:

class ClassWithStaticMethod {

  static staticMethod = () => {
    return ('staticMethod');
  };

  static staticMethod2 = function() {
    const yee = this.staticMethod();
    return 'staticMethod2 '+yee;
  };

}

console.log(ClassWithStaticMethod.staticMethod2());
like image 164
CertainPerformance Avatar answered Sep 21 '22 10:09

CertainPerformance


That's one quirk with arrow functions when it comes to general use: they have generic scoping of this. (That's why we have to use function() if you want a better call stack). In the second method, this refers to the calling context: window.

As mentioned below in the comment, do not use the short-hand syntax for your convenience; there is a reason we have so many options.

To fix it, you can just use function() to define the second function; or () in the object case.

This, however, would work:

class ClassWithStaticMethod2 {

  static staticMethod = () => {
    return ('staticMethod');
  };

  static staticMethod2 = function() {
    console.log(this)
    const yee = this.staticMethod();
    return 'staticMethod2 '+yee;
  };

}

Check it out here.

like image 40
weirdpanda Avatar answered Sep 21 '22 10:09

weirdpanda