A Function That Calls Itself
JavaScript Recursion
Recursion is a function that calls itself with a smaller piece of the problem. Every recursion needs a base case to stop.
What you'll learn
- Write a recursive function with a base case
- Recognize when recursion is the natural shape
- Avoid blowing the call stack
A recursive function calls itself. Every recursive function has two parts:
- Base case — when to stop.
- Recursive case — call yourself with a smaller piece of the problem.
Get both right and recursion is elegant. Forget the base case and you’ll crash the stack.
A Classic: Factorial
The factorial of n is n × (n-1) × (n-2) × … × 1.
function factorial(n) {
if (n <= 1) return 1; // base case
return n * factorial(n - 1); // recursive case
}
console.log(factorial(5)); // 120 (5 * 4 * 3 * 2 * 1)
console.log(factorial(0)); // 1
console.log(factorial(1)); // 1 How it unfolds:
factorial(5)
= 5 * factorial(4)
= 5 * (4 * factorial(3))
= 5 * (4 * (3 * factorial(2)))
= 5 * (4 * (3 * (2 * factorial(1))))
= 5 * (4 * (3 * (2 * 1)))
= 120
When Recursion Shines
Recursion is natural when the problem definition is recursive:
- A nested tree of comments, where each comment can have replies.
- A nested folder structure.
- A nested HTML/DOM tree.
- Mathematical sequences (factorial, Fibonacci, exponentiation).
function deepSum(arr) {
let total = 0;
for (const item of arr) {
if (Array.isArray(item)) {
total += deepSum(item); // recurse into nested array
} else {
total += item;
}
}
return total;
}
console.log(deepSum([1, 2, [3, [4, 5]], 6])); // 21 Forgetting the Base Case
Without a base case, the function calls itself forever. JavaScript’s
call stack has a limit — you’ll get RangeError: Maximum call stack size exceeded.
function broken(n) {
return n * broken(n - 1); // no base case!
}
try {
broken(5);
} catch (e) {
console.log(e.message);
// "Maximum call stack size exceeded"
} Recursion vs Iteration
Many problems can be solved either way. For straightforward sequences, iteration is usually faster and lighter on memory.
function factorialIter(n) {
let result = 1;
for (let i = 2; i <= n; i++) result *= i;
return result;
}
function factorialRec(n) {
return n <= 1 ? 1 : n * factorialRec(n - 1);
}
console.log(factorialIter(5), factorialRec(5)); // 120 120 Up Next
The most surprising keyword in JavaScript — this.