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?
-
Besides, if you want to implicitly return an object you must have parentheses around it since it will conflict with the block braces:
-
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
);
}