Learn by reading through in order

Function Declarations and Function Expressions — Arguments and return

Learn function declarations, arguments and return, function expressions, and why a missing return gives you undefined.

If you write the tax-included price formula directly in three places — the product list, the cart, and the order confirmation — then a tax rate change means fixing all three, and any screen you miss keeps showing the old amount.

This article covers function declarations, which give a piece of logic a name you can call, function expressions, which store a function in a variable as a value, and the value that return sends back.

Naming Logic So You Can Call It — function Declarations and Parameters

The logic for a product's tax-included price is the same every time; only the unit price changes. Since the price you pass in is the only difference, you can give the calculation itself a name, and then the list and the cart simply call it by that name.

A function (a named block of code that you can call as many times as you like) is declared in the form function name(parameters) { body }. The parameters in the parentheses are variables that receive a value on each call, and the value you write after return (the return value) goes back to the caller.

// Give the tax-included price logic the name taxIncluded
function taxIncluded(price) {
  const tax = Math.floor(price * 0.1);
  return price + tax;             // Send the calculated value back to the caller
}

// Call the same function with different unit prices
console.log(taxIncluded(1200));   // 1320
console.log(taxIncluded(980));    // 1078

// If you forget to pass a value, price is left undefined
console.log(taxIncluded());       // NaN
Three Different Calls to the Same Function
taxIncluded(price)definitiontaxIncluded(1200)taxIncluded(980)taxIncluded()price is 1200tax is 120price is 980tax is 98price is undefinedtax is NaNReturns 1320Returns 1078Returns NaNpasses a valuepasses a valuepasses nothing
When the value that goes into price changes, so does the value that comes back. A call that passes no value leaves price as undefined, and the result is NaN.

price receives only the value, so whether you write 1200 directly or pass a variable like itemPrice, the function works exactly the same way.

Display training session lengths in the form "X hr Y min". lectureMinutes and practiceMinutes are already declared.

① Declare a function that takes minutes and returns a string in the form "X hr Y min".

② Display the lecture length as "Lecture: X hr Y min".

③ Display the lab length as "Lab: X hr Y min".

④ Display the two combined as "Total: X hr Y min".

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

JavaScript / TypeScript Editor

Run code to see output

Taking Multiple Arguments — Matched by Position

When the discount rate varies by membership tier or sale, a function that takes only the unit price isn't enough. If the caller can pass the discount rate too, the calculation stays in one place and only the rate is decided at the call site.

Separate parameters with commas. The values at the call site are matched in the order you write them: the first value goes into the first parameter, the second into the second. They aren't matched by name, so passing them in the wrong order is still valid code, and nothing warns you.

// Take a unit price and a discount rate, and return the discounted price
function applyDiscount(price, rate) {
  return Math.floor(price * (1 - rate));
}

// The first value goes into price, the second into rate
console.log(applyDiscount(2400, 0.2));    // 1920
console.log(applyDiscount(2400, 0.05));   // 2280

// Even with the order swapped, the calculation still runs
console.log(applyDiscount(0.2, 2400));    // -480
Arguments Are Matched by Position
Pass(2400, 0.2)price is 2400rate is 0.2Compute2400 × 0.8Returns 1920Pass(0.2, 2400)price is 0.2rate is 2400Compute0.2 × -2399Returns -480
The same two values passed to applyDiscount, with only their order changed. Swapping them doesn't cause an error — only the result changes.

A call shows only the values, so reading applyDiscount(0.2, 2400) won't reveal the mix-up. When you get an impossible value like -480, check the order of the values in the call against the function's definition.

Work out the amount due for an order using two functions. unitPrice, quantity, shippingFee, and couponAmount are already declared.

① Declare a function that takes a unit price and a quantity and returns the subtotal.

② Declare a function that takes the subtotal, shipping fee, and discount amount, in that order, and returns the amount due.

③ Pass ①'s return value to ② and display "Total due: X yen".

④ Set the shipping fee to 0 and display "With free shipping: X yen".

JavaScript / TypeScript Editor

Run code to see output

Treating Functions as Values — Function Expressions and Variables

Standard and express shipping use entirely different formulas. Instead of spelling out which one to use at every call site, you can store the function itself in a variable, and the caller just calls that variable.

A function expression (a way of assigning a function to a variable as a value) is an assignment statement written as const name = function (parameters) { body };. A function declaration is ready before the code starts running from top to bottom, whereas a function expression's variable only receives the function when the assignment line runs (the mechanism is covered in the article on scope and hoisting).

// A function declaration can be called even from lines above it
console.log(expressShipping(1.5));       // 900

function expressShipping(weight) {
  return weight <= 2 ? 900 : 1300;
}

// Function expression: assign a function to a variable as a value
const normalShipping = function (weight) {
  return weight <= 2 ? 500 : 800;
};

// Without parentheses, the function itself goes into another variable
const feeRule = normalShipping;
console.log(feeRule(3));                 // 800
console.log(typeof feeRule);             // function
console.log(typeof normalShipping(3));   // number
Can You Call It from an Earlier Line?
Declared withfunctionCalled on a linebefore declarationSet up beforethe code runsReturns 900Put in a variableby an expressionCalled on a linebefore assignmentThe variable hasno function yetStops withReferenceError
Calling it on a line before the assignment stops with a ReferenceError. A function stored by a function expression can't be called until the assignment line runs.

The full error message is ReferenceError: Cannot access 'normalShipping' before initialization. Also note the feeRule line in the code above: assigning a function name without parentheses puts the function itself into another variable.

With and Without Parentheses
feeRule =normalShippingThe functionitself goes intypeof isfunctionCallable lateras feeRule(3)feeRule =normalShipping(3)The body runs and800 goes intypeof isnumberfeeRule(3) is aTypeError
Without parentheses, the function itself goes into the variable; with them, the result of running it does. If you add parentheses to a function you meant to call later, all you're left with is its return value.

Declare the Same Name Twice and the Later One Wins

Because function declarations are set up before the code runs, if you declare two with the same name, even a call on the line right after the first one runs the later body. Nothing stops execution, so a duplicate name far away in the file is easy to miss. With a const function expression, the second declaration is a SyntaxError, and the code never starts running.

Switch how the payment fee is calculated based on membership type. amount and isPremium are already declared.

① Write standardFee, which returns a 3% fee, and premiumFee, which returns a 1% fee, as function expressions (round down).

② Use isPremium to pick one of them and store it in applyFee.

③ Call applyFee and display "Fee: X yen".

④ Call standardFee directly and display "For regular members: X yen".

JavaScript / TypeScript Editor

Run code to see output

What Happens Without a Return Value — Forgetting return

If a function uses console.log, text appears on screen when you call it. Since something shows up, it looks like it works, but if you store its return value in a variable and use it, the string you expected isn't there.

return sends a value back and ends the function right there. A function without return returns undefined — displaying something and returning a value are two separate actions. console.log only prints to the screen; it hands nothing back to the caller.

// With return: the text goes back to the caller
function formatLabel(name, stock) {
  return `${name} (${stock} left)`;
  console.log("Unreachable");        // Comes after return, so it never runs
}

// Without return: it prints, but the return value is undefined
function printLabel(name, stock) {
  console.log(`${name} (${stock} left)`);
}

const label = formatLabel("Desk Lamp", 3);
console.log(label);      // Desk Lamp (3 left)

const printed = printLabel("USB Hub", 5);    // USB Hub (5 left)
console.log(printed);    // undefined
How the function is writtenWhat happens when calledWhat the caller gets
Returns the text with returnThe text goes back to the callerDesk Lamp (3 left)
Has only console.logPrints to the screen but returns nothingundefined
console.log after returnLines after return don't runThe text still comes back

When the caller is going to use the value, hand it back with return instead of displaying it.

A Line Break After return Means No Value Comes Back

If you break the line right after return and put the value on the next line, JavaScript treats the statement as ending on the return line, and the function returns undefined. It's an easy mistake to make when you move a long template literal to its own line for readability. Always start the value on the same line as return.

Add shipping to get the amount due. orderTotal, largeOrderTotal, and shippingFee (a function that's supposed to return the shipping fee) are already declared.

① Display orderTotal plus shipping as "Total due: X yen".

② Display largeOrderTotal in the same form.

③ Declare shippingFeeFixed, which returns the shipping fee as a number for any total.

④ Redo ①'s display using shippingFeeFixed.

JavaScript / TypeScript Editor

Run code to see output
QUIZ

Knowledge Check

Answer each question one by one.

Q1If you declare function double(n) { n * 2; } and run console.log(double(4));, what gets displayed?

Q2If you call function fee(price, rate) { return price * rate; } as fee(0.2, 1000), what goes into price?

Q3What happens if you call calc(1) on a line before the assignment const calc = function (n) { return n + 1; };?