Skip to main content

What is a closure?

A closure is a function that remembers the variables from the scope where it was created — even after that scope has finished executing. You’ve already been using closures without knowing it. If you’ve written a function inside another function and used a variable from the outer function, that’s a closure.
createGreeter has finished running, but sayHello still remembers that greeting was "Hello". That’s a closure.

Comparing to Python

Closures are not “a JavaScript thing” — Python has them too. If you’ve written a nested function that uses a variable from the outer function, you’ve already used closures.
Same idea in both languages: the inner function keeps access to greeting after the outer function returns.

Why closures matter

Closures aren’t an abstract concept you need to master — they’re a pattern that shows up naturally in JavaScript. Here are the places you’ll actually use them.

Callbacks with context

Each logger “remembers” its prefix. You create it once and use it everywhere.

Event handlers in loops

Each click handler is a closure that captures its own copy of i. This is why let (block-scoped) works correctly in loops but var (function-scoped) doesn’t.
Python mental model: this is the same family of problem as Python’s “late binding” in loops (for example, lambdas in a loop all using the final value). In JavaScript, let usually gives you the behavior you wanted automatically.

Data privacy

The count variable is completely private. The only way to interact with it is through the returned functions. This pattern is useful for creating modules and encapsulated state.

Closures in React

You use closures in React without thinking about it. Every event handler inside a component is a closure:
handleSubmit remembers query from the component scope. Every time the component re-renders, a new closure is created with the latest value of query.
This is why React state “works” — your event handlers are closures that capture the current state values. When you hear about “stale closures” in React, it means a function captured an old value of state. The useEffect dependency array exists to manage this.

Don’t overthink it

Closures sound complicated when explained in theory, but they’re a natural consequence of two things you already understand:
  1. Functions can be defined inside other functions
  2. Inner functions can access outer variables (lexical scope)
That’s it. When the inner function outlives the outer function, it keeps access to those variables. That’s a closure.
Don’t try to memorize closure rules. Write functions inside functions, use variables from the outer scope when it’s natural, and you’re using closures. The concept will solidify through practice.
If you’re a Python web dev, you’ve likely seen closures in decorator factories (functions that return decorators). JavaScript callbacks and React event handlers use the same underlying idea constantly.

What’s next?

You’ve covered the core of JavaScript — variables, types, strings, functions, scope, and closures. Now let’s learn how to work with collections of data: arrays and objects.

Arrays

Store and access collections of data