Functions
A function is a reusable block of code that takes inputs, runs some logic, and (optionally) returns a value. Functions are the smallest unit of organisation in JavaScript — almost every program is "a tree of functions calling each other". Understanding declarations, parameters, return values and the small surprises around hoisting is the first big step from "I can write a script" to "I can write a program".
Declaring a function
The classic shape is the function declaration: the keyword function, a name, a parameter list, and a body.
function greet(name) {
return "Hello, " + name + "!";
}
console.log(greet("Ada"));Hello, Ada!
Three things are happening: the function is defined (the engine learns about it), called with the argument "Ada", and the result of the call is logged. Each call runs the body top-to-bottom with the parameter name bound to whatever was passed in.
Calling a function and returning a value
A function returns a value either with an explicit return statement or, if there is no return, implicitly returns undefined. As soon as a return executes, the function exits — even from inside a loop.
function firstEven(numbers) {
for (const n of numbers) {
if (n % 2 === 0) return n; // exits immediately
}
// no return — implicit "return undefined"
}
console.log(firstEven([1, 3, 4, 7])); // 4
console.log(firstEven([1, 3, 5])); // undefinedParameters and arguments
The names in the parentheses are parameters (the slots). The values you pass when calling are arguments (what fills the slots). JavaScript is permissive: missing arguments become undefined, extra arguments are silently ignored.
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // 5
console.log(add(2)); // 2 + undefined = NaN
console.log(add(2, 3, 4, 5)); // 5 — extras ignoredMost modern code prefers explicit defaults to avoid the NaN surprise — see Default Parameters.
Functions are values
A function is just another value, like a number or a string. You can store it in a variable, put it in an array, pass it to another function, or return it from one. This is what makes JavaScript a functional language at its core.
function double(n) { return n * 2; }
const fn = double; // assign the function to another name
console.log(fn(10)); // 20
const operations = [double, n => n + 1];
console.log(operations[0](5)); // 10
console.log(operations[1](5)); // 6
function applyTwice(f, x) {
return f(f(x));
}
console.log(applyTwice(double, 3)); // 12Function declarations are hoisted
A function declaration is hoisted — the engine knows about the whole function before the script starts running. That means you can call it above the line where it is written:
sayHi(); // works! prints "hi"
function sayHi() {
console.log("hi");
}This only applies to declarations created with the function keyword at the top level of a scope. Function expressions and arrow functions assigned to const/let are not hoisted the same way — they follow the rules of the variable they are bound to. We cover this in detail in Hoisting.
Local scope and parameters
Every function call creates a fresh scope. Variables declared with let or const inside the function only exist for the duration of that call. Parameters behave like local variables.
function makeMessage(name) {
const greeting = "Hello, " + name; // local to this call
return greeting;
}
console.log(makeMessage("Lin"));
// console.log(greeting); // ReferenceError — not visible out here