Functions: Reusable Code Blocks
Functions are the building blocks of JavaScript programs. They let you write code once and reuse it many times. A function is a named block of code that can accept inputs (parameters), do something, and optionally return a value.
// Function declaration
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet("Alice")); // "Hello, Alice!"
// Parameters vs Arguments:
// name is a PARAMETER (in the definition)
// "Alice" is an ARGUMENT (when calling)
// Multiple parameters
function add(a, b) {
return a + b;
}
console.log(add(3, 4)); // 7
// Default parameters (ES6)
function greetWithDefault(name = "World") {
return `Hello, ${name}!`;
}
console.log(greetWithDefault()); // "Hello, World!"
console.log(greetWithDefault("Alice")); // "Hello, Alice!"
// Default can be any expression:
function createUser(name, role = "user", createdAt = new Date()) {
return { name, role, createdAt };
}
Function Expressions
A function can also be stored in a variable. These are called function expressions. The key difference from declarations is hoisting behavior.
// Function expression — anonymous
const multiply = function(a, b) {
return a * b;
};
// Named function expression — useful for recursion and debugging
const factorial = function fact(n) {
if (n <= 1) return 1;
return n * fact(n - 1); // can call itself by its name
};
// Hoisting difference:
console.log(declared()); // ✅ Works! Function declarations are hoisted
console.log(expressed()); // ❌ TypeError: expressed is not a function
function declared() { return "I'm hoisted!"; }
const expressed = function() { return "I'm NOT hoisted!"; };
// Immediately Invoked Function Expression (IIFE)
const result = (function() {
const privateVar = "I'm private";
return { message: privateVar };
})();
console.log(result.message); // "I'm private"
Return Values
// Functions without return → return undefined
function doSomething() {
const x = 5; // no return
}
console.log(doSomething()); // undefined
// Early return — exit function based on condition
function divide(a, b) {
if (b === 0) return null; // early exit
return a / b;
}
// Return multiple values via object or array
function getMinMax(arr) {
return {
min: Math.min(...arr),
max: Math.max(...arr)
};
}
const { min, max } = getMinMax([3, 1, 4, 1, 5, 9]);
console.log(min, max); // 1, 9
// Return array
function getFullName(first, last) {
return [first + " " + last, first, last];
}
const [full, firstName, lastName] = getFullName("John", "Doe");
Rest Parameters & Arguments
// Rest parameters — collect remaining arguments into array
function sum(...numbers) {
return numbers.reduce((total, n) => total + n, 0);
}
console.log(sum(1, 2, 3, 4, 5)); // 15
console.log(sum(10, 20)); // 30
// Mix with regular parameters
function logWithPrefix(prefix, ...messages) {
messages.forEach(msg => console.log(`[${prefix}] ${msg}`));
}
logWithPrefix("ERROR", "File not found", "Connection lost");
// arguments object (old way, avoid in modern code)
function oldStyle() {
console.log(arguments); // array-like object of all args
// but you can't use array methods on it!
}
// Use rest params instead:
function newStyle(...args) {
console.log(args); // actual array — .map(), .filter() work!
}
⚡ Key Takeaways
- Function declarations are hoisted; function expressions are not
- Default parameters make your functions more robust and self-documenting
- Always
returnexplicitly — functions returnundefinedwithout it - Return objects or arrays to return multiple values
- Use rest parameters (
...args) instead of the oldargumentsobject - Guard clauses with early returns keep functions flat and readable
🎯 Practice Exercises
EXERCISE 1
Write a function clamp(value, min, max) that returns value clamped between min and max. Test edge cases.
EXERCISE 2
Create a function using rest params that takes a list of scores and returns an object with min, max, average, and total.
EXERCISE 3 — CHALLENGE
Write a function pipe(...fns) that takes multiple functions and returns a new function that applies them left to right. E.g., pipe(double, addOne)(5) → 11.