Your Sunday, upgraded. Free live AI class · 5 PM ISTReserve your seat
PROGRAMMING LANGUAGES

Understand JavaScript Closures through Event Handlers and Counters

Closures explain why a callback remembers a value, why some loops capture the 'wrong' variable and how private state works without classes.

On this page

The core idea

A closure is a function together with the variables from the scope where it was created. When an inner function is defined inside an outer function, it keeps access to the outer function's variables even after the outer function has returned. Event handlers, timers and callbacks rely on this constantly. Closures capture variables, not snapshots of values, so if the variable changes later, the closure sees the new value.

A practical approach

Step 1

When a callback uses a variable from outside itself, identify which scope that variable belongs to.

Step 2

Prefer let and const over var in loops; let creates a new binding for each iteration, so each callback captures its own value.

Step 3

Use closures to create private state, such as a counter function that keeps its count hidden from the rest of the program.

Step 4

In React and other frameworks, remember that a handler created during one render closes over that render's values; read the latest value through state setters or refs when needed.

Step 5

Avoid capturing large objects in long-lived callbacks unintentionally, because the closure keeps them in memory.

Worked example

A page attaches click handlers to five course buttons inside a for loop using var i, and every button opens course 5. All five handlers share the same var binding, which equals 5 by the time anyone clicks. Changing var to let gives each iteration its own binding, and each button opens the correct course.

A mistake to avoid

Do not assume a closure stores the value a variable had when the function was created. It stores access to the variable itself; if the variable is reassigned before the callback runs, the callback sees the reassigned value.

Try it yourself

Write a function makeCounter() that returns an object with increment and current methods sharing a private count. Then write the buggy var loop from the example, observe the problem and fix it in two ways: with let and with a function that takes the index as a parameter.

Your implementation checklist

  • I can identify which scope a callback's variables come from
  • Loops use let or const, not var
  • Private state uses closures where appropriate
  • I understand stale values in framework handlers
  • Long-lived callbacks do not capture unnecessary large objects

Share or cite this guide

Innovate with Ajay Editorial (2026-10-07). Understand JavaScript Closures through Event Handlers and Counters. https://innovatewithajay.com/blogs/understand-javascript-closures

Editorial approach, sources and corrections

YOUR NEXT CHAPTER

You have the curiosity.
Let’s turn it into capability.

Start with a practical workshop or bring a specific question to Ajay.

Chat with Ajay