Skip to main content

Arrow function

The ES6 JavaScript update has introduced arrow functions, which is another way to declare and use functions. Here are the benefits they bring:

  • More concise
  • this is picked up from surroundings
  • implicit return

Sample code

  • Concision and implicit return
function double(x) { return x * 2; } // Traditional way
console.log(double(2)) // 4
const double = x => x * 2; // Same function written as an arrow function with implicit return
console.log(double(2)) // 4
  • this reference [Important concept]

In an arrow function, this is equal to the this value of the enclosing execution context. Basically, with arrow functions, you don't have to do the "that = this" trick before calling a function inside a function anymore.

function myFunc() {
this.myVar = 0;
setTimeout(() => {
this.myVar++;
console.log(this.myVar) // 1
}, 0);
}

Detailed explanation

Concision

Arrow functions are more concise than traditional functions in many ways. Let's review all the possible cases:

  • Implicit VS Explicit return

An explicit return is a function where the return keyword is used in its body.

  function double(x) {
return x * 2; // this function explicitly returns x * 2, `return` keyword is used
}

In the traditional way of writing functions, the return was always explicit. But with arrow functions, you can do implicit return which means that you don't need to use the keyword return to return a value.

  const double = (x) => {
return x * 2; // Explicit return here
}

Since this function only returns something (no instructions before the return keyword) we can do an implicit return.

  const double = (x) => x * 2; // Correct, returns x*2

To do so, we only need to remove the brackets and the return keyword. That's why it's called an implicit return, the return keyword is not there, but this function will indeed return x * 2.

Note: If your function does not return a value (with side effects), it doesn't do an explicit nor an implicit return.

When to use parentheses?

  1. Besides, if you want to implicitly return an object you must have parentheses around it since it will conflict with the block braces:

  2. To return a multi-line statement (such as an object literal), it’s necessary to use () instead of to wrap your function body.

const getPerson = () => ({ name: "Nick", age: 24 })
console.log(getPerson()) // { name: "Nick", age: 24 } -- object implicitly returned by arrow function
  • Only one argument

If your function only takes one parameter, you can omit the parentheses around it. If we take back the above double code:

  const double = (x) => x * 2; // this arrow function only takes one parameter

Parentheses around the parameter can be avoided:

  const double = x => x * 2; // this arrow function only takes one parameter
  • No arguments

When there is no argument provided to an arrow function, you need to provide parentheses, or it won't be valid syntax.

  () => { // parentheses are provided, everything is fine
const x = 2;
return x;
}
  => { // No parentheses, this won't work!
const x = 2;
return x;
}

this reference (Important concept)

To understand this subtlety introduced with arrow functions, you must know how this behaves in JavaScript.

In an arrow function, this is equal to the this value of the enclosing execution context. What it means is that an arrow function doesn't create a new this, it grabs it from its surrounding instead.

Without arrow function, if you wanted to access a variable from this in a function inside a function, you had to use the that = this or self = this trick.

For instance, using setTimeout function inside myFunc:

function myFunc() {
this.myVar = 0;
var that = this; // that = this trick
setTimeout(
function() { // A new *this* is created in this function scope
that.myVar++;
console.log(that.myVar) // 1

console.log(this.myVar) // undefined -- see function declaration above
},
0
);
}

But with arrow function, this is taken from its surrounding:

function myFunc() {
this.myVar = 0;
setTimeout(
() => { // this taken from surrounding, meaning myFunc here
this.myVar++;
console.log(this.myVar) // 1
},
0
);
}

References