Understanding Arrow Functions in ES6


ES6 has introduced arrow functions.

These functions have several advantages:

  • Much more concise.
  • Add implicit returns.
  • Does not rebind the value of this.

In this post, we will discuss the above features, and describe how they make Javascript function syntax much cleaner.

Let’s dive into some examples of Arrow functions in ES6.

Let’s start with an Array:

Now, imagine we wanted to write a new function that mapped over this array and added is cool to each string contained with it. Here’s what you might have in ES5:

Now let’s see how we can do this in a much more concise manner using ES6 and arrow functions:

The first thing you can do is remove the function keyword and use fat arrow notation, like so:

const fullNames2 = names.map((name) => {
  return `${name} is cool`;


//=> => [‘erik is cool’, ‘joe is cool’, ‘sarah is cool’]

If you only have a single parameter, you can actually remove those extra parenthesis around that argument. Here’s an example of what that would look like using the above code:

const fullNames2 = names.map(name => {
  return `${name} is cool’

Implicit Returns in Javascript Functions

In ES5 or earlier, you would use an explicit return to write out exactly what is returned in a method. You no longer need to do this in ES6 when you use Arrow functions.

Here is an example of the same function as above with the same return. You can see that I am not using the curly brackets around the function in this example, nor am I using the parenthesis.

const fullNames3 = names.map(name => `${name} is cool’);

Concise! Almost Ruby like!

If you have no arguments at all, you’ll need to pass empty parenthesis like this:

const fullNames3 = names.map(() => `Erik is cool’);

Arrow functions are always anonymous functions.

You’ll notice that none of the above functions have names. That’s because functions are all anonymous when you use arrow functions.

If you want to use arrow function syntax with and still name your function, you’ll need to assign the function to a variable, like so:

Cool right? A bit strange looking and less explicit, but still quite cool!

A few more Arrow Function examples:

What happens if we want to populate a new object using Arrow Functions?

Let’s say we want to build a website that lists out race contestants. We will have an array of racers and their respective position in the race.

The array might look like this:

const winners = ['racer1', 'racer2', 'racer3', 'racer4'];

In another const we have the race our contestants were running:

const race = '100m dash'

Now, ideally we would like to have an object for each racer, showing their relative position, name, and what race they ran.

This is what our ideal object would look like:

  name: 'racer1',
  race: 'position'
  place: 1

Let’s take a look at how we might do that with Arrow Functions:

const results = winners.map((winner, i) => ({name: winner, race: race, place: i}));

Couple of important things here:

You will notice that I have parenthesis around the function arguments. That’s because I have two arguments. You can only omit those parenthesis if you have one arg.

Notice that I have put the object into parenthesis as well. Why did I do that? Because I want to implicitly return the result of this map function.

Since the presence of curly brackets without the parenthesis would imply that I want to explicitly return the value, the function throws an error because I am not doing so.

By adding the parenthesis I indicate that these curly brackets represent an object body. That wraps up our example functions. If you have any questions or would like more arrow function examples, don’t hesitate to reach out and chat!

When NOT to use an arrow function:

Before you go buck wild and start using arrow functions everywhere, let’s consider a couple of cases where you won’t want to use them.

As a general rule, you probably do not want to use arrow functions whenever you are working with this. That’s because arrow functions do not load the variable this into the local context when the function is called.

When you are using an arrow function, this will be scoped to the Global Execution Context (if you need a refresher on Execution Contexts, check out my two part series on closures and execution contexts

Ok. Let’s dive in and look at a code example.

Let’s say I have const button = document.querySelector(‘.button’);

This button const points to a DOM button element. Now let’s say we want to add an event listener to this button, so when the button is pressed, an action will be triggered.

Here’s what that code might look like with your arrow function:

const button = document.querySelector(‘.button’);

buttton.addEventListener(‘click, () => {
  this.classList.toggle(‘on’); //=> error!!! This is defined globally.

You can see that we are invoking an arrow function here that does not take any arguments, leaving the parenthesis in tact, and specifying an explicit return.

So what’s the problem here? Simple, the all important this keyword does not reference button here as you would expect but rather references the global execution context.

To get this to work, you’ll need to revert to the old arrow function syntax, the working function is written below:

buttton.addEventListener(‘click, function()  {
this.classList.toggle(‘on’); //=> error!!! This is defined globally.


Arrow functions are a brand new addition to ES6 that make writing functions fun and fast.

But Arrow Functions have their limits. In instances where you need access to this in the context of a specific function, or you want to explicitly name a function, you will need to stick to the standard function syntax.


Please enter your comment!
Please enter your name here