ES6, or ECMAScript 2015, brought us many great changes to the language of JavaScript. One such feature is Arrow Functions. That's what we'll dive into in this article - get to reading!
What is an Arrow Function Expression?
An Arrow Function Expression is simply a new syntax to write function expressions as we've done before. In a lot of cases it can be much shorter to write which is great. If your task requires less typing you'll get more done in the same amount of time!
Granted you understand it - which I most certainly did not in my first encounters with the mighty =>
.
Here's a very basic example (which there will be more of):
/* * These are equivalent * */
// ES5
function func() {
console.log('Function Expression example.')
}
func()
// ES6
const arrow = () => {
console.log('Arrow Function Expression.')
}
arrow()
There are multiple aspects to the usage of Arrow Functions such as when it's best to use and not use them and some small gotchas on when they behave differently than an normal Function Expression. We won't cover them all here but we will cover some of the bigger ones.
Which is better?
Wrong question to ask. You can accomplish your task using either method. People have opinions on this subject all around - but lets face it that will never change.
However, there are certain scenarios where a strong case can be made to use or not use an Arrow Function.
When to Use
- When your resulting code will be shorter and more concise
- When your code becomes more readable
- When you feel like it!
When not to Use
- As an object method directly
- When your resulting code isn't any shorter or concise
- When your code can become more confusing or hard to read and understand
- When you do not feel like it!
Keep in mind it largely comes down to personal preference on what you believe is more readable, more concise, less confusing, etc. As mentioned there are a couple things to be aware of when choosing which route to take.
Arrow Function: To code or not to code?
One big item to know is Arrow Functions are lexically bound. Let's take a look at a couple examples first:
// ES5
var person = {
name: 'Foo Bar',
logName: function logName() {
setTimeout(function() {
console.log(this.name)
}.bind(this), 1000)
}
}
In order for the logName()
method to actually log out the name
property we must ensure the setTimeout
binds this
. We see that it is chained at the end of setTimeout
- if we did not do that then this
would actually be undefined
since the callback function of setTimeout
does not have its own this
. We explicitly bind it to the this
of logName
which is of course person
.
// ES6
var person = {
name: 'Foo Bar',
logName: function logName() {
setTimeout(() => {
console.log(this.name)
}, 1000) // No binding of 'this'
}
}
This time with Arrow Functions we do not have to ensure binding of this
to properly log it. IN THIS SCENARIO. (Gotcha comin' up...)
The catch here is that Arrow Functions cannot be bound to a this
so it will go up in scope to find the value of this
in the context which it was called - AKA lexically bound.
It's not recommended to use Arrow Functions directly as object methods like the following:
var person = {
name: 'Foo Bar',
logName: () => { // => instead of function expression
setTimeout(() => {
console.log(this.name)
}, 1000)
}
}
Now this.name
will return undefined
. It's a little confusing but a key thing to remember is that again an Arrow Function will not have a this
attached to itself. I like to think of Arrow Functions just passing the buck.
The console.log
tries to evaluate this
so it goes to setTimeout
- it says "I don't know a
this
maybe try to asklogName
" - we get to
logName
(which is also defined as an => so it cannot bind athis
) and ask and it says "this
doesn't ring a bell, maybe askperson
?" - now we ask
person
and it's like "Hey I don't have any property calledthis
I can't help."
Eventually we get all the way to the global Window
object because that's the default when this
isn't bound to anything in the context which we called it.
Why use an Arrow Function?
Okay, that was confusing. this
in relation to Arrow Functions is arguably the hardest thing to grasp. So let's talk about something easier to grasp and results in some clean looking code.
As mentioned, Arrow Functions can result in much shorter, cleaner code for us and especially in short function definitions or when using map
or reduce
.
Let's take a look.
// ES5
function addTwoNums(x, y) {
return x + y
}
// ES6
const addTwoNums = (x, y) => {
return x + y
}
Doesn't look any shorter in ES6, right? One great feature of Arrow Functions is if we have one statement and want to return we don't use the {} or the return
keyword.
const addTwoNums = (x, y) => x + y
There's an implicit return when no braces or return
is present with an Arrow Function. This really helps when it comes to the readability of a map
or reduce
usage.
const nums = [1, 2, 3]
const doubledNums = nums.map(num => num * 2)
You may have noticed this time when using the Arrow Function in map
we didn't put parenthesis around the parameter.
When there is only one parameter for an Arrow Function the parenthesis are optional.
So parenthesis can be optional and in certain scenarios the brackets and return
can be omitted providing us multiple ways to write the same code. Going for the shortest code is usually what I would do - but again, personal preference.
/* * These are ALL equivalent * */
// ES5
const doubledNums = nums.map(function(num) {
return num * 2
})
// ES6
const doubledNums = nums.map((num) => {
return num * 2
})
// ES6: No brackets - implicit return
const doubledNums = nums.map((num) => num * 2)
// ES6: Single parameter - no parameter parenthesis
const doubledNums = nums.map(num => num * 2)
Arrow Functions have more characteristics and gotchas than listed here but these are the basics I focused on to get a grasp. Once you get an understanding of these concepts take a peek at the MDN Arrow Functions page. You'll find plenty more use cases and confusing things to learn!
Don't get me wrong - I keep saying confusing because it's true! I learn more each day - new things I hadn't heard of or known and how my understanding of something wasn't quite right. Let me know in the comments if there's an explanation here that isn't quite right or if there's an interesting gotcha you know of.
I still love JavaScript and this Tweet speaks to that pretty well!
Dear Developers,
One thing is for sure: I may drive you crazy sometimes; but in the end, you fall in love with me each and every day again.
best regards,
JavaScript ❤️16:16 PM - 11 Jul 2020
Top comments (0)