Learn by reading through in order

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
Rewriting a Function Expression as an Arrow Function
Functionexpressionconst name =function (price){ returnprice * 0.02 }Returns 64for 3200Arrowfunctionconst name =(price) =>{ returnprice * 0.02 }Returns 64for 3200Only this differs
The assignment and the body stay the same; only the middle part changes. The function keyword disappears, and => follows the parameters.

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.

Rewrite yearlyFee, a function expression that calculates a subscription's yearly price, as an arrow function. standardMonthly and premiumMonthly are also already declared.

① Turn yearlyFee into an arrow function without changing how it behaves.

② Display the yearly price for Standard and Premium as "Standard: X yen" and "Premium: X yen".

③ Display the difference between the two prices from ② as "Difference: X yen".

(If it runs correctly, an explanation will appear.)

JavaScript / TypeScript Editor

Run code to see output

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
Shortening the Same Function Step by Step
(price) => {return price + 500; }Nothing omittedprice => {return price + 500; }One parameter:drop the ( )price =>price + 500One expression:drop { }, return
The three steps differ only in how they're written; they all do the same calculation. Whichever one you pass 1200 to, you get 1700 back.

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.

Create functions for a shipping estimate, each with a single-expression body. shippingFee and boxCount are already declared.

① Write discountFee in one line: it takes a shipping fee and returns the amount with 10% off (rounded down).

② Write totalFee in one line: it takes a shipping fee and a box count and returns the total shipping.

③ Call ① and display "Discounted: X yen".

④ Pass ①'s result to ② and display "Discounted total: X yen".

JavaScript / TypeScript Editor

Run code to see output

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
Block Body or Object?
(name) =>{ label: name }Braces are readas a block bodyNo returnis writtenReturns undefined(name) =>({ label: name })Inside ( ) is readas an expressionThe braces becomean objectReturnsan object
The same braces are read differently depending on whether they're wrapped in parentheses. Unwrapped braces are treated as a block body with no return.

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.

Build shipping quotes. orderTotals and freeLine are already declared; shipping is 500 yen for amounts below freeLine and free otherwise.

① Write toQuote in one line: it takes an amount and returns an object with the keys total and shippingFee, in that order.

② Display the first quote with JSON.stringify.

③ For the second quote, display "Total due: X yen" (amount + shipping).

④ Display the combined shipping for both quotes as "Total shipping: X yen".

JavaScript / TypeScript Editor

Run code to see output

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
Whether the Item Was Opened Decides Which return Runs
returnMessage(12, false)limit is 1412 > 14is falseGoes on to thelast returnreturnMessage(12, true)limit is 712 > 7is trueEnds at the returninside the if
Only the call for an opened item reaches the return inside the if. The function ends there and never gets to the return after it.

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 writtenWhat happens in the bodyWhat the caller gets back
days => expressionIts value comes back as-is12 days since purchase
(days, isOpened) => { ...; return }The value of the return that ran2 days left / Return window closed
days => { expression only }Evaluated, but never returnedundefined

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.

Calculate how many units to restock, rounded to full lots. targetStock, currentStock, and lotSize are already declared.

① Write planRestock as an arrow function with a block body that takes the target stock, the current stock, and the units per lot.

② In the body, work out the shortage and return it rounded up to full lots (0 if there's no shortage).

③ Call it with the current stock and display "Restock: X units".

④ Display the result the same way when the current stock equals the target.

JavaScript / TypeScript Editor

Run code to see output
QUIZ

Knowledge Check

Answer each question one by one.

Q1If you declare const twice = n => n * 2; and display twice(4), what gets displayed?

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?