Finally Understanding JavaScript Closures

Closures are one of those JavaScript concepts that confused me for a long time. Now they’re finally making sense.

What Is a Closure?

A closure is when a function remembers variables from its outer scope, even after that outer function has finished executing.

That definition didn’t help me at first. Examples did.

Simple Example

function outer() {
  const message = "Hello";
  
  function inner() {
    console.log(message); // Can access 'message'
  }
  
  return inner;
}

const myFunction = outer();
myFunction(); // Logs "Hello"

inner “closes over” the message variable. Even after outer finishes, inner still has access to message.

Practical Use: Private Variables

function createCounter() {
  let count = 0; // Private variable
  
  return {
    increment() {
      count++;
      return count;
    },
    decrement() {
      count--;
      return count;
    },
    getCount() {
      return count;
    }
  };
}

const counter = createCounter();
counter.increment(); // 1
counter.increment(); // 2
counter.getCount(); // 2

count is private you can only access it through the methods.

Common Use: Event Handlers

function setupButtons() {
  for (let i = 0; i < 3; i++) {
    const button = document.getElementById(`btn-${i}`);
    button.addEventListener('click', function() {
      console.log(`Button ${i} clicked`);
    });
  }
}

Each click handler closes over its own i value.

The Classic Interview Question

// What does this log?
for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
// Logs: 3, 3, 3 (not 0, 1, 2!)

Why? Because var is function-scoped, and all callbacks share the same i.

Fix with let (block-scoped):

for (let i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}
// Logs: 0, 1, 2

Or with a closure:

for (var i = 0; i < 3; i++) {
  (function(j) {
    setTimeout(function() {
      console.log(j);
    }, 1000);
  })(i);
}

Why Closures Matter

Data privacy: Create private variables

Function factories: Create customized functions

Callbacks: Maintain state in async operations

Module pattern: Organize code with private and public parts

What’s Clicking

Closures aren’t a special feature they’re just how JavaScript works. Functions always have access to their outer scope.

Understanding closures is helping me understand:

  • How React hooks work
  • Module patterns
  • Callback behavior
  • Scope and context

Closures went from confusing to fundamental. They’re everywhere in JavaScript once you know what to look for.