Arrow Functions

Open the project folder

In our starter files, open the index.html page from this lessons folder:

03.Functions > 06.Arrow-functions

Using arrow function

In ES2015 we were given a new, optional way of creating function expressions, called arrow functions. These are a shorter way to write function expressions, but it is not just the syntax, they can also behave differently to regular functions.

At the top of the starter file, we have a regular function expression:

const startGame = () {
  alert('game started')
};

To convert this to an arrow function, there is a few steps we need to take:

// 1. remove function keyword
const startGame = () {
  alert('game started')
};

// 2. Add arrow =>
const startGame = () => {
  alert('game started');
};

// 3. Call function
startGame();

We started by saying arrow functions were a shorter syntax, but this does not look much different. This is a valid arrow function but we can go even further. Since this function only has one line of code inside we can remove the curly braces and bring it all onto one line:

const startGame = () => alert('game started');

We also don’t need the return keyword for single lines like this either, we only need if our function has multiple lines, and this makes sense since it cannot guess which line we want to return.

Arrow functions can also take in parameters like a regular function:

const startGame = (a, b) => {
  alert('game started');
};

And we don’t even need the surrounding brackets if we only have one parameter:

const startGame = a => {
  alert('game started');
};

The starter file has some code commented out, this is the same example we used previously:

let checkRecipes = {
  currentRecipes: 137,
  maxRecipes: 1000,
  checkAllergies: function (recipe, ingredient) {
    const hasIngredient = recipe.includes(ingredient);
    return hasIngredient;
  },
  numberOfIngredients: function (recipe) {
    return recipe.length;
  },
  recipesLeft: function () {
    return maxRecipes - currentRecipes;
  },
};

Uncomment this out to make it active and remove the previous example.

With what we know about arrow functions, we can change the recipesLeft method to make use of them:

recipesLeft: () => this.maxRecipes - this.currentRecipes,

At the bottom of the file we log this method to the console:

console.log(checkRecipes.recipesLeft());

The console displays the value of NaN (Not a Number). This method is not working as it did before. This is because of the way arrow functions handle the this keyword.

Arrow functions with this

And more precisely, they don’t have their own this, which is why we see not a number in the console. Let’ try to log this and see what we get, to see it, we first need to go back to a multi-line function (surrounding curly braces {}):

recipesLeft: () => {
  console.log(this);
  return this.maxRecipes - this.currentRecipes;
},

Unlike earlier where this referred to the parent object, arrow functions do not have their own this, so it refers to the global object, which is the window.

Therefore, it is often advised to not use an arrow function for creating methods, since we cannot access the other object properties. The way this is handled is a design choice and it is intended to work this way.

Arrow functions with array methods

We have already briefly looked at arrow functions with array methods. They are often used with these because of the shorter syntax. Let’s compare a small example. This is how a regular function looks when passed to an array method:

brownies.map(function (ingredient) {
  return ingredient.toUpperCase();
});

And this is the equivalent using an arrow function:

brownies.map(ingredient => ingredient.toUpperCase());

So, you can see why the shorter version is often used.

Since arrow functions are newer, often people use them by default. This can be fine if that is what you prefer, and they do have some benefits such as the shorter form. But because arrow functions are a newer way of doing things, it does not mean we should always use them exclusively.

If you look closely, they are also anonymous, which means they do not have an identifier other than maybe a variable we assign them to. And also, the differences with the this keyword behaviour.