Ecmascript 6 arrow functions seem ideally suited to be used as methods in classes since they are not subject to the calling context messing with the "this" reference. I can't see how to use them the way I expect, though. The following is a class which shows two ways I can see to 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 the new this handling and one should be able to pass them to click handlers, and other functions needing callbacks and not have to worry about the callback being invoked in some what whiich causes "this" to unexpectedly point to something other than the appropriate instance of the object.
Both say2 and say3 seem awkward, though. say2 is defined in the constructor and say3 is really a wrapper around an arrow functions. I was expecting some sytax which would allow me to replace the say() line with something like
say: () => console.log(this.name)
But as near as I can tell, you cannot do anything like this. So the question is, to use arrow functions as methods is the approach of say2 or say3 reasonable. Is there a better way?
In the ES6 grammar, the body of a class may only consist of method definitions, so arrow function expressions are not permitted here. This is a simplified snippet of the relevant portions 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, which suffers from the same issues with this binding as normal functions. However, you can get around that using bind when you pass it, as in element.addEventListener('click', this.say.bind(this));.say2 will work, but you lose the convenience of specifying methods outside of the constructor.say3 won't work - while it is syntactically valid, it will be parsed as a method, whose body consists of a single arrow function. 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 print to the console.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With