๐ What is recursion?
Recursion is when a function calls itself to solve smaller instances of a problem, until it reaches a base case that ends the loop.
It's like looking into a mirror facing another mirror โ the pattern repeats until it fades.
๐ Anatomy of a recursive function
Every recursive function has two parts:
- Base Case: The condition that stops recursion.
- Recursive Case: The part where the function calls itself.
function countdown(n) {
if (n <= 0) return; // base case
console.log(n);
countdown(n - 1); // recursive case
}
countdown(3); // 3, 2, 1
๐ง Why use recursion?
Recursion is ideal when a problem:
- Has a naturally nested or hierarchical structure (like trees, folders, JSON).
- Can be broken into smaller subproblems (like factorial, Fibonacci).
- Requires backtracking or exploring all paths (like permutations, maze solvers).
๐ Iteration vs recursion
Iteration:
for (let i = 5; i > 0; i--) console.log(i);
Recursion:
function print(n) {
if (n === 0) return;
console.log(n);
print(n - 1);
}
Both work โ but recursion can make code cleaner for problems with nested depth (like traversing a DOM tree).
๐งฎ Classic examples
1. Factorial
function factorial(n) {
if (n === 0) return 1;
return n * factorial(n - 1);
}
factorial(5); // 120
2. Fibonacci
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
fibonacci(6); // 8
> โ ๏ธ Be careful: this version is exponential. You can optimize it with memoization.
๐ฒ Real-world use: tree traversal
Imagine this nested folder structure:
const tree = {
name: 'root',
children: [
{ name: 'child1', children: [] },
{
name: 'child2',
children: [
{ name: 'subchild', children: [] }
]
}
]
};
Recursive traversal:
function printTree(node) {
console.log(node.name);
for (const child of node.children) {
printTree(child);
}
}
๐ก Tips for writing recursive code
- Always define a clear base case to avoid infinite loops.
- Think in terms of smaller subproblems.
- Consider tail recursion or memoization for performance.
- Use the call stack wisely: too much recursion = stack overflow.
๐งช Bonus: flattening nested arrays
function flatten(arr) {
return arr.reduce((acc, el) =>
Array.isArray(el) ? acc.concat(flatten(el)) : acc.concat(el)
, []);
}
flatten([1, [2, [3, 4]], 5]); // [1, 2, 3, 4, 5]
๐งต Conclusion
Recursion can feel magical โ or intimidating. But once you grasp its structure and use cases, it becomes a powerful mental model, especially for:
- Trees (DOM, JSON)
- Graphs
- Backtracking (games, puzzles)
- Functional programming