Q1If you declare const twice = n => n * 2; and display twice(4), what gets displayed?
Arrow Functions — Shorthand and Returning Objects
Learn how => rewrites a function, when you can drop parentheses and braces, how to return an object, and block bodies.
Even for short logic like formatting each element of an array, a function expression means writing function, braces, and return every time, and the actual logic gets buried under syntax.
This article covers arrow functions, which create functions with =>, and the shorthand forms that let you drop parentheses and braces.
Writing the Same Logic Shorter — The Basic Arrow Function
Functions that take a value, do one calculation, and return the result are common — working out reward points from a purchase amount, for example. Yet each one needs the function keyword, braces, and return, so when function expressions pile up, the syntax stands out more than the calculations.
An arrow function (a way of creating a function using =>) is written as const name = (parameters) => { body };. You drop the function keyword and put => between the parameter list and the body, then assign it to a variable and call it just like a function expression.
// What you've used so far: a function expression, which assigns a function to a variable
const rewardPoints = function (price) {
return price * 0.02;
};
// Arrow function
const rewardPointsArrow = (price) => {
return price * 0.02;
};
console.log(rewardPoints(3200)); // 64
console.log(rewardPointsArrow(3200)); // 64
console.log(typeof rewardPointsArrow); // function
The two names differ only so you can compare them side by side. Both have a typeof of function, and they receive parameters and use return in exactly the same way. When certain conditions are met, you can shorten this basic form further by dropping the parentheses or return.
Dropping Parentheses and return — One Parameter and Implicit Return
Some logic fits in a single expression, like adding shipping to an amount or checking whether a total is 5000 yen or more. In the basic form, even a one-line calculation takes three lines once you add the braces and return, and when functions like these pile up, braces and return take up most of the code.
If there's exactly one parameter, you can drop the parentheses around it. And if the body is a single expression, you can drop the braces and return too. What makes this work is implicit return (the rule that the value of the body's expression becomes the return value as-is).
// Basic form: parameter parentheses, body braces, and return all written out
const withFee = (price) => {
return price + 500;
};
// Shorthand
const withFeeShort = price => price + 500;
const isFreeShipping = total => total >= 5000;
console.log(withFee(1200)); // 1700
console.log(withFeeShort(1200)); // 1700
console.log(isFreeShipping(4800)); // false
The body of isFreeShipping is a single comparison, so passing 4800 returns false, the result of 4800 >= 5000. Implicit return hands back whatever the expression evaluates to, so a calculation and a comparison are written in exactly the same way.
You Can't Drop the Parentheses with 0 or 2 Parameters
If you remove the parentheses when there are no parameters, as in () => expression, or when there are two or more, as in (price, rate) => expression, you get a SyntaxError and the code never starts running. If you add a parameter later, remember to put the parentheses back. With one parameter, keeping them, as in (price) => expression, is also fine.
Returning an Object — Wrapping It in Parentheses
When you format a record for display, you often want to return an object with several keys rather than a single number. But if you use the shorthand and write the object's braces right after =>, you get undefined instead of an object.
Braces written after => are read as a block body (an area where you can write any number of statements), not as an object. To return an object, wrap it in parentheses, as in (name) => ({ name: name }), so the braces are read as an expression.
// Plain braces are read as a block body
const toBadge = (name) => { label: name };
console.log(toBadge("Wireless Mouse")); // undefined
// Wrapped in parentheses, the braces are read as an object
const toCard = (name, stock) => ({ name: name, inStock: stock > 0 });
const card = toCard("Wireless Mouse", 4);
console.log(JSON.stringify(card)); // {"name":"Wireless Mouse","inStock":true}
console.log(card.inStock); // true
With two or more keys, as in { name: name, inStock: true }, the contents can't be parsed as statements, so a SyntaxError keeps the code from running. With a single key, label: name happens to be a valid statement (a label followed by an expression), so there's no error and you silently get undefined, which is easy to miss until you display the result.
When the Logic Takes Multiple Lines — Block Bodies and return
Some logic has to calculate an intermediate value or branch on a condition before deciding what to return, like working out how many days a customer has left to return a product. The single-expression shorthand has nowhere to keep an intermediate value and no way to return a different value for each condition.
A block body can contain statements like const and if, but implicit return doesn't apply there, so you write return to return a value. A function can have several return statements, and it ends at whichever one runs first.
// Single-expression body: the expression's value comes back as-is
const shortMessage = (days) => `${days} days since purchase`;
console.log(shortMessage(12)); // 12 days since purchase
// Block body: build intermediate values and return per condition
const returnMessage = (days, isOpened) => {
const limit = isOpened ? 7 : 14;
if (days > limit) {
return "Return window closed"; // The function ends here
}
return `${limit - days} days left`;
};
console.log(returnMessage(12, false)); // 2 days left
console.log(returnMessage(12, true)); // Return window closed
// Without return, you get undefined
const brokenMessage = (days) => { `${days} days left`; };
console.log(brokenMessage(12)); // undefined
If you return early for the cases that fail the check, the lines after that only need to handle the normal case. The table below shows what the caller gets back for each way of writing the body.
| How the body is written | What happens in the body | What the caller gets back |
|---|---|---|
| days => expression | Its value comes back as-is | 12 days since purchase |
| (days, isOpened) => { ...; return } | The value of the return that ran | 2 days left / Return window closed |
| days => { expression only } | Evaluated, but never returned | undefined |
this Works Differently from Regular Functions
Inside an object's method, you can use this (a keyword that refers to the object the method was called on). An arrow function doesn't have its own this; it uses the this of the surrounding code. The article on classes in the object-oriented programming chapter comes back to this difference.
Knowledge Check
Answer each question one by one.
Q2What does calling const toItem = name => { label: name }; return?
Q3In an arrow function with two parameters, what happens if you drop the parentheses around them?