30 min·intermediate

Lesson 2

Closures

Build a practical mental model for closures and use it in working JavaScript.

By the end, you will be able to…

  • Explain closures in your own words
  • Use closures in a small program
  • Recognize and debug a common failure mode

Build the mental model

A closure is a function that remembers the variables from the scope it was created in, even after that outer function has returned. Each call to makeCounter creates a fresh, private count that only its returned function can touch.

makeCounter() scope

let count = 0

returned function — still reads & updates count
A closure retains its outer scope

Syntax and working example

Read the code from inputs to output. Predict what it prints, then run it and change one value.

Working example
Expected output: 1 2 3

Why this matters

Closures are how JavaScript creates private state without classes — count above cannot be reached or corrupted from outside the returned function.

Real-world example

React's useState hook is built on this exact closure pattern to give each component instance its own private state.

Common mistakes

  • Expecting two calls to makeCounter() to share the same count (each call creates an independent closure)
  • Creating closures inside a loop with var and being surprised they all share the same final value
  • Not realizing the outer variables stay alive in memory as long as the closure does

Try it yourself

Challenge

Write makeBankAccount(balance) returning { deposit, getBalance } that keeps balance private.

Practice

Knowledge check

What does a closure allow a returned function to do?

Summary

A closure retains access to its defining scope's variables even after that scope has returned — the basis for private state.