What is the correct way to use Ecmascript 6 arrow functions as methods in classes?

Ecmascript 6's arrow functions seem to be ideal for use as methods in classes, since they are not subject to the calling context being drawn into the "this" reference. I cannot figure out how to use them the way I expect. Below is a class that shows two ways that I can use them:

class Person {

constructor(aName) {
    this.name = aName;
    this.say2 = () => console.log(this.name);
}

say() { console.log(this.name) }

say3() { () => consolve.log(this.name) }

}

      

Both say2 and say3 will use this new handling, and should be able to pass them to click handlers and other functions that need callbacks, and shouldn't worry about calling a callback that unexpectedly calls "this" indicate something different. than the corresponding object instance.

Both say2 and say3 seem awkward. say2 is defined in the constructor, and say3 is really a wrapper around the arrow functions. I was expecting some sitax that would allow me to replace the say () line with something like

say: () => console.log(this.name)

      

But as far as I can tell, you cannot do anything like this. So the question is to use arrow functions as methods are say2 or say3 approach sane. Is there a better way?

Thanks for any input.

+3


source to share


1 answer


In ES6 grammar, the body of a class can only consist of method definitions , so arrow function expressions are not allowed here. This is a simplified snippet of the relevant parts of the grammar:

ClassBody :
    ClassElementList

ClassElementList :
    ClassElement
    ClassElementList ClassElement

ClassElement :
    MethodDefinition
    static MethodDefinition
    ;

MethodDefinition :
    PropertyName ( StrictFormalParameters ) { FunctionBody }
    GeneratorMethod
    get PropertyName ( ) { FunctionBody }
    set PropertyName ( PropertySetParameterList ) { FunctionBody }

      

So in your example:



class Person {

    constructor(aName) {
        this.name = aName;
        this.say2 = () => console.log(this.name);
    }

    say() { console.log(this.name) }

    say3() { () => console.log(this.name) }

}

      

  • say

    is a normal method definition that suffers from the same binding problems this

    as normal functions. However, you can work around this by using bind

    when passing it, as in element.addEventListener('click', this.say.bind(this));

    .
  • say2

    will work, but you lose the convenience of specifying methods outside the constructor.
  • say3

    won't work - although it is syntactically correct, it will be parsed as a method whose body consists of a single arrow function. Just to clarify, say3() { () => console.log(this.name) }

    and say3() { return () => console.log(this.name) }

    differ in that the former will do nothing and return undefined

    , whereas the latter will return an arrow function expression which, when called, will be printed to the console.
+1


source







All Articles