Recursion
Recursion is a function calling itself with a smaller version of the same problem, terminating at a base case. It's the natural tool whenever a problem has self-similar structure: tree traversal (the DOM, the file system, AST parsing), divide-and-conquer sorting, graph DFS, anything defined inductively. Two things to watch for: every recursion needs a base case (miss it and you stack-overflow), and recomputing the same subproblem repeatedly turns linear work into exponential — that's exactly when to reach for memoisation. An iterative loop can always replace recursion (sometimes more performantly), but the recursive version is usually shorter and closer to the problem's natural shape. Languages with tail-call optimisation (Scheme, Scala, sometimes JS) avoid stack growth; JavaScript engines mostly don't, so deep recursions need iteration.