Functions and Scope

5.Write It Once, Use It Everywhere

A

In this chapter

We'll learn to package code into functions — with parameters, arguments and return values — understand scope, see how programs take input and give output, and handle errors so bad input can't produce a wrong price.

14–16 min

The Problem in Real Life

The checkout page, the mobile app and the refund page all need the same pricing rules. Right now the rules live only inside the checkout page's code.

John draws a box on a sticky note and writes "price" on it. "Put the rules in here, once. Everyone who needs a price gives this box the cart, and gets a number back. Change the rules once, and every page changes with them."

J

Write it once, give it a good name, and use it everywhere.

John

Code Copied Into Every Page vs. One Reusable Function

Same rules, three places

Three copies of the pricing rules will slowly drift apart — and customers will see three different prices.

In and out

Pricing needs inputs (the cart, the buyer) and gives one output (the total).

Bad input must not slip through

A negative ticket count or a missing price should stop the code, not produce a strange total.

Functions, Scope and Handling Errors

A function is a named block of code that does one job. You write it once and call (run) it whenever you need that job done. You've already used functions: console.log(...) and Math.round(...) are functions someone else wrote.

  • Defining a function: function calculateTotal(cart, isStudent) { ... } creates a function called calculateTotal. The code inside the curly brackets is its body.
  • Parameters: the names inside the brackets in the definition — cart and isStudent. They're placeholders for the inputs the function needs.
  • Arguments: the actual values you pass in when you call it — calculateTotal(myCart, true). Here myCart and true are the arguments; inside the function they're known as cart and isStudent.
  • Return value: the result the function sends back, with the return keyword. return totalCents; ends the function and hands that number to whoever called it. A function without return gives back nothing (undefined in JavaScript).
  • Scope: where a variable can be used. A variable created inside a function (a local variable) exists only inside that function, and disappears when it ends. A variable created outside all functions (a global variable) can be used everywhere — which is convenient but risky, because any code can change it. In JavaScript, let and const are also limited to the curly-bracket block they're created in. Keep variables in the smallest scope that works.
Table — Parameters vs. arguments
TermWhere it appearsExample
ParameterIn the function definitionfunction calculateTotal(cart, isStudent)
ArgumentIn the function callcalculateTotal(myCart, true)
Return valueWhat the call gives back13497
Table — Local vs. global variables
FeatureLocalGlobal
CreatedInside a function or blockOutside all functions
UsableOnly inside that function or blockEverywhere in the program
Lives untilThe function or block endsThe program ends
RiskLowAny code can change it by mistake

A function: inputs in, one result out

Arguments

myCart, true

passed in as parameters

calculateTotal(cart, isStudent)

check input → add up → apply discount

returns

Return value

13497 (cents)

Or: an error

"Ticket has no price"

The pricing rules as one reusable function
const GROUP_SIZE = 5;
function calculateTotal(cart, isStudent) {
if (!Array.isArray(cart)) {
throw new Error("Cart must be a list of tickets");
}
let totalCents = 0; // local: only exists inside this function
for (const ticket of cart) {
if (typeof ticket.priceCents !== "number" || ticket.priceCents < 0) {
throw new Error("Ticket has no valid price");
}
totalCents += ticket.priceCents;
}
if (isStudent) {
return Math.round(totalCents * 0.8);
} else if (cart.length >= GROUP_SIZE) {
return Math.round(totalCents * 0.9);
}
return totalCents;
}
// Using it, with error handling
try {
const total = calculateTotal(myCart, false);
console.log("Total in cents:", total);
} catch (error) {
console.log("Could not price this order:", error.message);
}

Input and output: every program takes input and produces output, just like the computers in Act 02. For a function, input is its arguments and output is its return value. For a whole program, input can come from a keyboard, a web form, a file or a network request; output can be text on a screen, a file, a web page or a response to another program. console.log is the simplest output — it prints text so you can see what's going on.

Handling errors: what if someone calls calculateTotal with a negative number of tickets, or a ticket with no price? The function shouldn't quietly return a nonsense number. Instead, it can throw an error — stop immediately and report what went wrong: throw new Error("Ticket has no price"). The code that called it can catch the error with try { ... } catch (error) { ... } and show the customer a helpful message instead of crashing. Validating input — checking it's sensible before using it — is one of the best ways to prevent bugs.

Anna moves all the pricing rules into one function, calculateTotal, with a check at the top that throws an error for bad input. The checkout page, the mobile app and the refund page now all call the same function. John reviews it and gives a thumbs-up: one place to change, one place to test.

Key Takeaway

A function packages one job under a name: parameters name its inputs, arguments are the values passed in, and return sends back the result. Variables live in a scope — keep them local. Validate inputs and throw errors for bad data, so a function never quietly returns a wrong answer.

Why This Matters

Functions are how all real software is organised — every feature in BlueTicket is built from hundreds of small functions calling each other. Good functions are easy to test (Act 17), easy to reuse, and safe because they check their input. And error handling is the difference between a customer seeing "please check your order" and a blank, broken page.

The function works. Anna opens her first pull request, and John reviews it. His comments aren't about whether it works — they're about whether the next person can understand it. That's the last skill in this Act.

Next