JavaScript Recursion

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.

4 min read Level 3/5 #recursion#functions#base-case
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:

  1. Base case — when to stop.
  2. 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.

Factorial script.js
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
▶ Preview: console

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).
Sum a deeply nested array script.js
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
▶ Preview: console

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.

The base-case crash script.js
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"
}
▶ Preview: console

Recursion vs Iteration

Many problems can be solved either way. For straightforward sequences, iteration is usually faster and lighter on memory.

Two solutions to factorial script.js
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
▶ Preview: console

Up Next

The most surprising keyword in JavaScript — this.

JavaScript this →