Arrow functions are a shorter way to write function expressions, introduced in ES6 (2015). You can skip the function keyword, and often the return keyword and the curly braces too. They are everywhere in modern JavaScript, especially for small callbacks.
const multiply = (a, b) => a * b;
console.log(multiply(4, 5));
An arrow function uses the => symbol (an equals sign and a greater-than sign, read as "goes to"). Watch the same function shrink step by step:
// 1. Regular function expression
const double = function(n) {
return n * 2;
};
// 2. Drop "function", add => after the parameters
const double = (n) => {
return n * 2;
};
// 3. One expression in the body? Drop the braces AND the return
const double = (n) => n * 2;
// 4. Exactly one parameter? The parentheses are optional
const double = n => n * 2;
All four versions behave the same when called: double(5) gives 10. (They are shown together to compare; you could not actually declare const double four times in one scope.)
Without braces, the arrow function automatically returns the value of its single expression. This is called an implicit return:
const add = (a, b) => a + b;
const isEven = n => n % 2 === 0;
const greet = name => `Hi, ${name}`;
const hello = () => "Hello World!";
console.log(add(2, 3), isEven(7), greet("Jo"), hello());
return when you also drop the braces. Mixing the two forms goes wrong:
const f1 = (x, y) => { x * y }; // braces, no return: gives undefined
const f2 = (x, y) => return x * y; // return, no braces: SyntaxError
const f3 = (x, y) => { return x * y }; // correct
const f4 = (x, y) => x * y; // correct
(W3Schools says f2 "will return undefined". It will not even run: it is a SyntaxError.) Because of this trap, some programmers always use braces and return.
const sayHi = () => "hi"; // no parameters: () required
const square = x => x * x; // one parameter: () optional
const area = (w, h) => w * h; // two or more: () required
const hello = (name = "you") => `Hello ${name}`; // defaults: () required
For more than one statement, use braces and an explicit return, exactly like a regular function:
const receipt = (price, qty) => {
const subtotal = price * qty;
const tax = subtotal * 0.08;
return (subtotal + tax).toFixed(2);
};
console.log(receipt(12.50, 4));
An arrow function is always an expression: it has to be stored in a variable, and like any function expression it cannot be used before its line:
hello();
const hello = () => "Hello";
Arrow functions make short callbacks far easier to read. Here is the repeat function from Function Expressions, called both ways:
function repeat(times, action) {
for (let i = 1; i <= times; i++) action(i);
}
repeat(2, function(n) {
console.log("Lap " + n);
});
repeat(2, n => console.log("Lap " + n)); // same thing, one line
A preview from the Arrays section: map runs a function on every item and collects the results into a new array. Arrow functions are made for this:
const prices = [10, 20, 30];
const withTax = prices.map(p => p * 1.08);
console.log(withTax);
(That last value is the decimal precision issue from JS Numbers.) The next lesson, JS Timers, uses arrow callbacks throughout.
This is a preview for the Objects section, where it matters. Braces right after => are always read as a function body, never as an object. To return an object with the short form, wrap it in parentheses:
const makeUser = name => ({ name: name }); // returns an object
const broken = name => { name: name }; // returns undefined!
In broken, JavaScript reads the braces as a function body containing a label called name, and there is no return, so it gives undefined. With two or more properties, like { x: x, y: y }, it is not even valid code: a SyntaxError.
| Feature | Regular | Arrow |
|---|---|---|
Own this | Yes | No: uses the surrounding one |
arguments object | Yes | No: use ...rest |
| Hoisted | Declarations only | No |
Usable with new | Yes | No (TypeError) |
The this difference matters most. In an object's method, this normally means "the object this method belongs to". An arrow function does not get its own this, so as a method it points somewhere else entirely. It gets a full lesson in the Objects section (Object this). The short version: do not use an arrow function as an object's method.
| Use arrows for | Avoid arrows for |
|---|---|
| Short functions | Object methods |
| Callbacks and array methods | Anything that needs its own this |
When you do not need this | Main, named functions you want hoisted |
undefinedthisWhich is the shortest correct arrow version of function triple(n) { return n * 3; }?
const triple = n => { n * 3 };const triple = n => n * 3;const triple = => n * 3;const triple = n => return n * 3;return, so it gives undefined. C has no parameter at all. D is a SyntaxError.What does this log?
const check = age => age >= 18 ? "adult" : "minor";
console.log(check(15));
minor. The whole ternary is the one expression, so it is returned implicitly.Which situation is a bad fit for an arrow function?
mapthisn => n * 2setTimeoutthis, so inside an object method this would not point at the object.triple into the shortest arrow formreturn, call it, and see undefinedmakeMultiplier from Function Expressions using two arrows: const makeMultiplier = f => n => n * f; and test itmap with an arrow function to double every number in [1, 2, 3, 4]