Declaring & Calling Functions
Intermediate · 18 min read · ▶ live playground · ✦ checkpoint
You don't want to write the same score message six times. A function is a reusable block of code you can call by name, like a recipe card you keep on the counter: write the steps once, then use them whenever the same job comes back.
Declare, then call
A function declaration is a statement that creates a named function with function, a name, parentheses, and a body inside {}:
function greetPlayer() {
console.log("Welcome, Mina.");
}
greetPlayer();
greetPlayer();→ Welcome, Mina., then Welcome, Mina. again — one declaration, two calls.
The declaration writes the recipe card. The call runs the function now, and the call syntax is the pair of parentheses after the name: greetPlayer().
Those parentheses matter. greetPlayer by itself is the function value. greetPlayer() runs it. That difference becomes useful later in this lesson, when you start moving functions around like any other value.
Parameters and arguments
Hard-coded functions are useful once. Better functions leave blanks.
A parameter is a named blank in a function declaration, and an argument is the real value you pass into that blank when you call the function:
function makeBadge(playerName, score) {
return `${playerName}: ${score} points`;
}
console.log(makeBadge("Mina", 42));
console.log(makeBadge("Rae", 35));→ Mina: 42 points, then Rae: 35 points — same recipe, different ingredients.
Inside the function, playerName and score behave like normal names. On the first call, playerName refers to "Mina" and score refers to 42. On the second call, those parameter names get fresh argument values.
The return value is the value a function hands back to the exact place where it was called. In console.log(makeBadge("Mina", 42));, JavaScript calls makeBadge, gets the returned string, then gives that string to console.log.
Try it — build a small score report
Run this once, then change the names and scores. Notice that one function can call another function, because a call is also an expression that produces a value.
At the › prompt, try addBonus(10, 5) or describeRun("Ari", 30, 7). The function declarations themselves echo undefined in the REPL because declarations create names; the calls are the pieces that produce the score strings.
Returning is not printing
console.log shows a value to a human. return gives a value back to the program. Those are different jobs.
function showReceipt(totalCents) {
console.log(`Paid ${totalCents} cents`);
}
const savedValue = showReceipt(975);
console.log("saved value:", savedValue);→ Paid 975 cents, then saved value: undefined.
If a function reaches the end without return, its return value is undefined, the primitive that means "no value was supplied here." That silent undefined is not a crash. It is JavaScript answering, "this function printed something, but it did not hand anything back."
Use return when later code needs the result:
function buildReceipt(totalCents) {
return `Paid ${totalCents} cents`;
}
const savedReceipt = buildReceipt(975);
console.log("saved receipt:", savedReceipt);→ saved receipt: Paid 975 cents — now the string is available for the next line.
return also stops the function immediately. Code after a return in the same path does not run. You'll use that for clean early-exit checks as your functions get bigger.
Function declarations vs. function expressions
A function expression creates a function as a value inside a larger expression, often assigned to a const name:
const cheerPlayer = function (playerName) {
return `Go, ${playerName}!`;
};
console.log(cheerPlayer("Mina"));→ Go, Mina!
Both shapes create callable functions:
- Function declaration:
function cheerPlayer(playerName) { ... } - Function expression:
const cheerPlayer = function (playerName) { ... };
For now, use function declarations for named, top-level helpers. Use function expressions when you specifically want to store a function in a variable or pass it around as a value. Arrow functions are a shorter function-expression syntax, and they arrive in lesson 5.2.
Functions are values
A function value is the function itself, not the result of calling it. That means you can assign it to another name, pass it as an argument, and return it from another function.
function shout(message) {
return message.toUpperCase();
}
const formatMood = shout;
function printMood(formatter, mood) {
console.log(formatter(mood));
}
function makeMoodLabeler() {
return function (mood) {
return `Mood: ${mood}`;
};
}
printMood(formatMood, "ready");
const labelMood = makeMoodLabeler();
console.log(labelMood("calm"));→ READY, then Mood: calm.
Read the key lines out loud:
const formatMood = shout;copies the function value. No parentheses, so nothing runs yet.printMood(formatMood, "ready");passes a function as an argument.return function (mood) { ... };returns a new function value.
That "function as data" idea is one of JavaScript's main superpowers. Lesson 5.5 turns it into the pattern where functions receive and return other functions on purpose; here you only need the foundation: parentheses call a function, no parentheses refer to the function value.
Why order sometimes does not matter
JavaScript registers function declarations before it starts running the top line of your code. That pre-registration is hoisting, and it is why this works:
console.log(openScoreboard("Mina"));
function openScoreboard(playerName) {
return `${playerName}'s board is ready.`;
}→ Mina's board is ready.
Do not stretch that rule too far. Function expressions assigned to const follow the normal const timing rule: the name is not usable before its line runs. This throws ReferenceError: Cannot access 'makeBadge' before initialization:
console.log(makeBadge("Mina"));
const makeBadge = function (playerName) {
return `${playerName} is ready.`;
};The full scope-and-hoisting story comes in lesson 5.4. The useful rule today is smaller: function declarations can be called before their line; function expressions stored in variables should be called after their assignment line.
Checkpoint
Answer all three to mark this lesson complete
You now have the core move: name a job, feed it arguments, and use the value it returns. Next, you keep the same ideas but write them with arrow functions, the compact function syntax JavaScript uses everywhere.