LEARN TO CODE | JAVASCRIPT | 02 FUNCTIONS AND COLLECTIONS

02.1 Functions, parameters and return values

Write a reusable function, pass values into it and use its returned result in another part of your program.

01 | STOP REPEATING THE SAME CALCULATION

A club sells tickets for different groups. Each time, the program multiplies the quantity by a price and adds a booking fee. Copying those statements for every group works at first, but a changed rule then needs several edits.

A function groups instructions into a named job you can run when needed. You define the job once, then call it with the values appropriate to each group.

Think of a small calculator with input slots and a result. The calculation stays the same; the supplied values can change. We will build that idea slowly, starting with a function that simply logs a message.

Keep index.html and script.js in the same VS Code folder. Put the current example into script.js, save it, open or refresh index.html in your browser and look in that page’s Developer Tools Console.

Replace the previous example unless a task explicitly says to add to it. Pasting several independent examples together can redeclare the same let or const name. The downloadable examples use a separate folder for each complete program.

02 | DEFINING DOES NOT MEAN RUNNING

function showWelcome() {
  console.log("Welcome to the coding club");
}

showWelcome();
showWelcome();

function introduces a function declaration. showWelcome is its name. The braces enclose its body : the statements executed when the function runs. The empty parentheses mean this function has no named parameters.

Writing the declaration makes the function available, but does not run its body at that point. Each showWelcome() call runs the body once. Two calls produce two messages.

showWelcome without parentheses refers to the function itself. showWelcome() calls it. This difference becomes important when you pass functions to array methods and, later, event listeners.

TRY IT YOURSELF

Remove both calls, leaving only the declaration. What appears in the console?

Reveal guidance

The function body produces no output, because nothing calls it. Put one call back and the message appears once.

03 | PARAMETERS ARE THE INPUT NAMES

function greetStudent(studentName) {
  console.log(`Hello, ${studentName}!`);
}

greetStudent("Alex");
greetStudent("Sam");

studentName is a parameter : a local name written in the function definition. "Alex" is an argument : the actual value supplied by a particular call.

On the first call, studentName holds "Alex" for that invocation. On the second, it holds "Sam". You do not need to rename the parameter for each student.

The parameter name does not have to match a variable at the call site. If const visitor = "Alex", then greetStudent(visitor) supplies the value stored in visitor to studentName.

Read the definition and call together
Part Example Role
Function name greetStudent Identifies the job
Parameter studentName Name used inside the function
Argument "Alex" Value supplied at a call
Function body console.log(...) Instructions run for that call

04 | RETURN PASSES A RESULT BACK

function calculateCost(quantity, price) {
  return quantity * price;
}

const total = calculateCost(3, 6);
console.log(total);

return evaluates the expression and passes its result back to the calling code. Here the call calculateCost(3, 6) produces 18, which is assigned to total.

The function does not print 18 itself. The console.log after the call chooses to display it. Another caller could use that same number in a larger calculation instead.

Read the two parameters in order: quantity receives 3 and price receives 6. With differently named values, the order still follows the call’s argument positions.

05 | TRACE THE WHOLE JOURNEY

A returned value travels back to the call
Step Where execution is Values or action
1 Calling statement Evaluate calculateCost(3, 6)
2 Function begins quantity = 3; price = 6
3 Return expression Calculate 3 * 6, producing 18
4 Back at the call The call’s result is 18; assign total = 18
5 Next statement console.log(total) logs 18

STEP THROUGH A FUNCTION CALL

Ready: the definition exists, but no call has run yet.

When a function returns, execution resumes at its caller. The body is not a separate program that keeps running afterwards.

06 | LOGGING AND RETURNING ARE DIFFERENT

function printCost(quantity, price) {
  console.log(quantity * price);
}

const result = printCost(3, 6);
console.log(result);

printCost logs 18, but it has no explicit returned value. Reaching the end of this ordinary function returns undefined. That is why result becomes undefined even though you saw a number in the console.

If a calculation must be reused, return it. Then let the caller decide whether to display, store or compare it. Logging is an observable action; it is not a substitute for returning useful data.

TRY IT YOURSELF

Repair printCost so the assigned result is 18 and there is only one logged line.

Reveal guidance
function calculateCost(quantity, price) {
  return quantity * price;
}
const result = calculateCost(3, 6);
console.log(result);

07 | RETURN ENDS THE CURRENT CALL

function deliveryFee(orderTotal) {
  if (orderTotal >= 20) {
    return 0;
  }
  return 3;
}

console.log(deliveryFee(25));
console.log(deliveryFee(12));

For 25, the condition is true and return 0 ends that invocation. The final return 3 is not executed on that route. For 12, execution skips the first return and reaches the second.

A function can have several return statements, but this ordinary call returns through only the route it actually takes. Statements after an executed return in the same body do not run.

Give every intended route a clear result when the caller expects a value. Accidentally missing a return in one branch is a common source of undefined.

08 | DEFAULT INPUTS AND TYPE ASSUMPTIONS

function finalCost(quantity, price, fee = 0) {
  return quantity * price + fee;
}

console.log(finalCost(2, 6));
console.log(finalCost(2, 6, 3));

A default parameter supplies a value when that argument is omitted or is undefined. Here fee becomes 0 on the first call. Passing null does not mean “use the default”.

JavaScript does not enforce numeric parameter types just because we named them quantity and price. These examples use known numeric values. A public form needs validation and conversion before calling its calculation.

Keep assumptions visible: a function that expects whole ticket quantities should not silently be treated as a complete validator for arbitrary browser input.

09 | FUNCTIONS CAN BE VALUES TOO

const double = (number) => {
  return number * 2;
};
console.log(double(4));

const triple = (number) => number * 3;
console.log(triple(4));

These are arrow functions assigned to const names. The arrow separates the parameter list from the body. In the first version, braces make a block body and return is explicit.

In the second, the expression immediately after the arrow is returned automatically. Adding braces changes that rule: { number * 3; } does not return the calculation by itself.

You do not need to convert every function to arrow syntax. We introduce it here because it is common in array methods. The declaration form remains a clear choice for many named jobs.

10 | COMBINE SMALL JOBS

function calculateSubtotal(quantity, price) {
  return quantity * price;
}
function deliveryFee(subtotal) {
  return subtotal >= 20 ? 0 : 3;
}

const subtotal = calculateSubtotal(3, 6);
const total = subtotal + deliveryFee(subtotal);
console.log(`Subtotal: ${subtotal}; total: ${total}`);

Each function has one small responsibility. The caller combines the results. The expression condition ? valueIfTrue : valueIfFalse is the conditional, or ternary, operator; this fee rule is the same as the if/return version above.

Use the longer if version if it is easier to read. Shorter code is not automatically clearer code.

11 | BUILD AND TEST YOUR OWN FUNCTION

TRY IT YOURSELF

Write area(width, height), returning the rectangle’s area. Call it for 4 by 3 and 5 by 2. Then log a message using each returned result.

Reveal guidance
function area(width, height) {
  return width * height;
}
console.log(`Area: ${area(4, 3)}`);
console.log(`Area: ${area(5, 2)}`);

Check more than one call so your function is not merely returning a fixed answer. Next, store a collection of related values in an array and process them with reusable functions.

KEEP LEARNING

Previous page 02.2 Arrays and array methods

Download Section 02 example programs

Further reading: Functions · Arrays · Objects · VS Code browser debugging