Two characters, an arrow, and the function fits on one line. That is why this form took over everywhere, especially in the functions handed to Array.map() or Array.filter().
It does more than shorten things, though. It changes the behavior of this, and that difference is the real reason to use it or to avoid it.
Definition
An arrow function is a function expression written with =>. It has no this, no arguments object and no prototype property of its own. This two-column table sums up the available forms.
| Spelling | What it does |
|---|---|
n => n * 2 | One parameter, implicit return |
(a, b) => a + b | Two parameters, implicit return |
() => { ... } | Full body, return required |
n => ({ n }) | Returning an object, parentheses required |
const double = (n) => n * 2;
const add = (a, b) => a + b;
const greet = (name) => {
const message = "Hello " + name;
return message;
};
const createProfile = (name) => ({ name, active: true });
console.log(double(21)); // 42
console.log(add(2, 3)); // 5
console.log(greet("Ada")); // Hello Ada
console.log(createProfile("Ada")); // { name: 'Ada', active: true }Braces open a body, they never describe an object. Hence the parentheses on the last line, which remove the ambiguity.
The real difference: this
An arrow reuses the this of the place where it is written, and nothing can change it afterward. That is what solves the classic callback problem.
const counter = {
total: 0,
increment() {
[1, 2, 3].forEach(() => {
this.total += 1; // this stays the counter
});
return this.total;
},
};
console.log(counter.increment()); // 3With a classic function in place of the arrow, this would no longer point at the object. See this binding for the full set of rules.
Three cases where to avoid it
- As an object method. Its
thiswould be the one of the file, not the one of the object. - As a constructor. Calling it with new throws an error, it was never meant for that.
- When you want
arguments. An arrow has none; use Rest (...) instead.
Frequently asked questions
Is an arrow faster than a classic function?
No, the performance difference is nil in practice. The choice comes down to readability and to the behavior of this, never to speed. Engines treat both forms the same way once the code is compiled.
Can it be given a name?
Indirectly. An arrow is always anonymous, but assigning it to a constant gives it a name in error traces, which is enough for debugging. It does not benefit from the Hoisting of function declarations, though: it must be declared before its first call.
Are parentheses needed around a single parameter?
The language makes them optional, and both spellings are valid. Most formatting setups add them systematically, so that adding a second parameter does not require touching the line. An automatic formatter settles that question once and for all.