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.
source to share
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 problemsthis
as normal functions. However, you can work around this by usingbind
when passing it, as inelement.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) }
andsay3() { return () => console.log(this.name) }
differ in that the former will do nothing and returnundefined
, whereas the latter will return an arrow function expression which, when called, will be printed to the console.
source to share