Functions

Understand how to declare, invoke, and parameterize functions in JavaScript, including default and rest parameters, return values, and scope.

A function is a reusable block of code that performs a task, optionally taking inputs and producing an output. Functions are the primary way JavaScript programs are organized into manageable, testable, reusable pieces.

Declaring and invoking a function

A function declaration starts with the function keyword, a name, a parenthesized parameter list, and a body in curly braces. Declaring a function does not run it — the code inside only executes when the function is invoked (called), which is done by writing the function's name followed by parentheses.

Function declarations are hoisted, meaning JavaScript moves their full definition to the top of their containing scope during compilation — this is why a function declaration can be called earlier in the code than where it is written, unlike function expressions.

Parameters vs arguments

Parameters are the named placeholders listed in a function's definition (function greet(name) { ... } — name is a parameter). Arguments are the actual values passed in when the function is called (greet("Ana") — "Ana" is the argument).

JavaScript does not enforce that the number of arguments matches the number of parameters: missing arguments become undefined inside the function, and extra arguments are simply ignored (unless captured with rest parameters).

return values

A return statement immediately exits the function and sends a value back to wherever the function was called. If a function has no return statement, or return is used with no value, the function implicitly returns undefined.

Any code written after a return statement inside the same block is unreachable and never executes, since return exits the function the moment it runs.

Default parameters

A default parameter lets you specify a fallback value that is used automatically if the caller omits that argument (or explicitly passes undefined). This removes the need for manual checks like param = param || defaultValue inside the function body.

Default values are evaluated at call time, and can even reference earlier parameters in the same list, e.g. function rect(width, height = width) sets height equal to width when height is not provided.

Rest parameters

A rest parameter, written with three dots before the final parameter name (...args), collects any remaining arguments passed to the function into a real array. This is how you write a function that accepts an unlimited or unknown number of arguments.

Only one rest parameter is allowed per function, and it must be the last parameter in the list, since it greedily collects everything from that position onward.

Scope

Every function creates its own scope: variables declared with let, const, or var inside a function are local to that function and are not visible outside it. This is what allows different functions to reuse the same variable names without conflicting.

A function can, however, read (and in some cases modify) variables declared in an outer scope that contains it — this is called lexical scoping, and it is the foundation for closures, a more advanced topic built directly on top of this behavior.

Function declaration anatomy

Parameters without a default become undefined if no argument is supplied. A rest parameter must come last and collects all remaining arguments into an array. return with no value (or no return statement at all) makes the function return undefined.

function functionName(param1, param2 = "default", ...rest) {
  // function body
  return param1 + param2;
}

const result = functionName("a", "b", 1, 2, 3);

Code Examples

add is declared with two parameters, invoked with the arguments 3 and 4, and its return value is stored in sum and printed. Expected result: 7 return a + b; sends the computed value back to the caller, which is then assigned to sum.

tax has a default of 0.08 that is used automatically when undefined is passed explicitly for Leo. items uses a rest parameter to gather every argument after tax into a real array, no matter how many prices are supplied. Expected result: Ana owes $110.00 Leo owes $43.20 Passing undefined explicitly for tax still triggers the default value (0.08), because default parameters only skip over an argument that is exactly undefined....items collects all remaining arguments into an array — items.reduce(...) then sums them.

function add(a, b) {
  return a + b;
}

const sum = add(3, 4);
console.log(sum);
function createInvoice(customer, tax = 0.08, ...items) {
  const subtotal = items.reduce((sum, price) => sum + price, 0);
  const total = subtotal * (1 + tax);
  return `${customer} owes $${total.toFixed(2)}`;
}

console.log(createInvoice("Ana", 0.1, 20, 30, 50));
console.log(createInvoice("Leo", undefined, 15, 25));

Function call and return flow

Arguments flow into the function as parameters; a return statement sends a single value back out to wherever the function was called.

caller code
       │
       │  add(3, 4)
       ▼
  ┌─────────────────┐
  │ function add(a,b)│   a = 3, b = 4
  │   return a + b;  │ ──────────────► computes 7
  └─────────────────┘
       │
       │  7 flows back to caller
       ▼
  const sum = 7;

Important Rules

Parameters are placeholders in the definition; arguments are the actual values passed at call time.

A function without an explicit return statement returns undefined.

Default parameters apply when an argument is omitted or is exactly undefined — not for null or other falsy values.

A rest parameter must be the last parameter and collects the remaining arguments as a real array.

Variables declared inside a function are scoped to that function and are not accessible from outside it.

Function declarations are hoisted and can be called before their definition appears in the code.

Where this shows up

Nearly all reusable logic in a real application lives in functions: calculating a shopping cart total, validating user input, formatting a date for display, or fetching and transforming data from an API — each is typically wrapped in its own named function.

function double(x) { x * 2; } console.log(double(5));

function double(x) { return x * 2; } console.log(double(5));

Without a return statement, the function computes x * 2 but never sends it back, so the function's result is undefined even though the calculation happened internally.

function sumAll(...numbers, label) {... } function sumAll(label,...numbers) {... }

A rest parameter must be the very last parameter in the list — putting anything after ...numbers is a SyntaxError, because the rest parameter greedily consumes everything from its position to the end of the arguments.

[Multiple Choice] What value does a function return if it has no return statement at all? A. null B. 0 C. undefined D. An empty string

C. undefined — A function with no return statement (or a bare return with no value) implicitly returns undefined.

[True / False] A rest parameter can appear anywhere in a function's parameter list, as long as there is at least one parameter after it. A. True B. False

B. False — False. A rest parameter must be the last parameter in the list, since it collects every remaining argument — placing another parameter after it is a SyntaxError.

Write a function formatName(first, last, middle = "") that returns the full name as "First Middle Last" if a middle name is given, or "First Last" if it is not.

function formatName(first, last, middle = "") { if (middle) { return ${first} ${middle} ${last}; } return ${first} ${last}; }

Check whether middle is a non-empty string before deciding which format to build.