A tutorial to JavaScript Arrow Functions
By Flavio Copes
Learn JavaScript arrow function syntax, implicit returns, lexical this, rest parameters, and when a regular function is the better choice.
Arrow functions are a compact way to write function expressions.
They were added in ES2015. Their most important difference is not the shorter syntax: arrow functions do not create their own this.
See the MDN arrow functions reference for the complete syntax.
Arrow function syntax
This regular function expression:
const greet = function(name) {
return `Hello, ${name}`
}
can be written as an arrow function:
const greet = name => {
return `Hello, ${name}`
}
Use parentheses for no parameters or multiple parameters:
const getMessage = () => 'Hello'
const add = (a, b) => a + b
With exactly one simple parameter, parentheses are optional:
const double = number => number * 2
Parameters with defaults, destructuring, or rest syntax need parentheses:
const greet = (name = 'friend') => `Hello, ${name}`
const getName = ({ name }) => name
const sum = (...numbers) => numbers.reduce((total, number) => total + number, 0)
Implicit return
An arrow function with an expression body returns that expression:
const double = number => number * 2
double(4) //8
Add curly braces when you need multiple statements. Then use return explicitly:
const double = number => {
const result = number * 2
return result
}
Wrap an object literal in parentheses for an implicit return:
const createUser = name => ({ name })
createUser('Flavio') //{ name: 'Flavio' }
Without the parentheses, JavaScript treats the braces as the function body.
Arrow functions use lexical this
An arrow function captures this from the surrounding scope. Calling it with a different receiver does not change that value.
This makes arrow functions useful inside callbacks:
const counter = {
value: 0,
start() {
setInterval(() => {
this.value += 1
}, 1000)
}
}
The arrow callback uses the same this as start().
Do not use an arrow function as an object method when you need this to refer to that object:
const car = {
model: 'Fiesta',
manufacturer: 'Ford',
fullName() {
return `${this.manufacturer} ${this.model}`
}
}
car.fullName() //'Ford Fiesta'
A regular method gets this from how it is called. An arrow function does not.
Arrow functions in event listeners
In a DOM listener written with a regular function, this equals event.currentTarget:
const link = document.querySelector('#link')
link.addEventListener('click', function(event) {
this === event.currentTarget //true
})
An arrow listener inherits this from outside. Use event.currentTarget when you want the element:
link.addEventListener('click', event => {
console.log(event.currentTarget)
})
Other differences from regular functions
Arrow functions also do not have their own:
argumentssupernew.target
Use rest parameters instead of arguments:
const logValues = (...values) => {
console.log(values)
}
Arrow functions cannot be used as constructors:
const Person = name => ({ name })
new Person('Flavio') //TypeError
They also cannot be generator functions.
Use arrow functions for short callbacks and lexical this. Use regular functions for constructors, generators, and methods that need a dynamic this.
Related posts about js: