JS Fat Arrow Functions
JS Fat Arrow Functions
Classical JavaScript function syntax doesn't provide for any flexibility, be that a 1 statement function or an unfortunate multi-page function. Every time you need a function you have to type out the dreaded function () {}
. More concise function syntax was one of the many reasons why CoffeeScript gained so much momentum back in the day. This is especially pronounced in the case of tiny callback functions. Lets look at a Promise chain:
Above is more or less plausible piece of code written using classical JavaScript function
syntax. Here is what the same code could look like rewritten using the arrow syntax:
A few important things to notice here:
We've lost
function
and{}
because all of our callback functions are one liners.We've lost
()
around the argument list when there's just one argument (rest arguments are an exception, eg(...args) => ...
)We've lost the
return
keyword because when omitting{}
, single line arrow functions perform an implicit return (these functions are often referred to as lambda functions in other languages).
It's important to reinforce the last point. Implicit return only happens for single statement arrow functions. When arrow function is declared with {}
, even if it's a single statement, implicit return does not happen:
Here's the really fun bit. Because our function has only one statement, we can still get rid of the {}
and it will look almost exactly like CoffeeScript syntax:
Yep, the example above is completely valid ES2015 syntax (I was also surprised that it compiles fine). When we talk about single statement arrow functions, it doesn't mean the statement can't be spread out to multiple lines for better comprehension.
There's one caveat, however, with omitting {}
from arrow functions -- how do you return an empty object, eg {}
?
Unfortunately there's no way to distinguish between empty block {}
and an object {}
. Because of that emptyObject()
evaluates to undefined
and {}
interpreted as empty block. To return an empty object from fat arrow functions you have to surround it with brackets like so ({})
:
Here's all of the above together:
Lexical this
this
The story of clobbering this
in JavaScript is a really old one. Each function
in JavaScript defines its own this
context, which is as easy to get around as it is annoying. The example below tries to display a clock that updates every second using jQuery:
When attempting to reference the DOM element this
set by each
in the setInterval
callback, we unfortunately get a brand new this
that belongs to the callback itself. A common way around this is to declare that
or self
variable:
The fat arrow functions allow you to solve this problem because they don't introduce their own this
:
What about arguments?
One of the caveats with arrow functions is that they also don't have their own arguments
variable like regular functions:
To reiterate, fat arrow functions don't have their own this
and arguments
. Having said that, you can still get all arguments passed into the arrow functions using rest parameters (also known as spread operator):
What about yield?
Fat arrow functions can't be used as generators. That's it -- no exceptions, no caveats and no workarounds.
Bottom Line
Fat arrow functions are one of my favorite additions to JavaScript. It might be very tempting to just start using =>
instead of function
everywhere. I've seen whole libraries written just using =>
and I don't think it's the right thing to do because of the special features that =>
introduces. I recommend using arrow functions only in places where you explicitly want to use the new features:
Single statement functions that immediately return (lambdas)
Functions that need to work with parent scope
this
Last updated