JavaScript is full of interesting features, and one of the most powerful (and sometimes confusing) is the closure. If you’ve ever returned a function from another function or seen variables that somehow “remember” their environment, you were probably looking at a closure.

In this article, we’ll break down what closures are, how they work, and why they’re so useful—no computer science degree required!


🧠 What is a closure?

A closure happens when a function remembers the variables from the scope in which it was created—even after that scope has finished running.

In simple terms:

> A closure gives you access to an outer function’s variables even after the outer function has returned.

Here’s a classic example:

function makeCounter() {
  let count = 0;

  return function () {
    count++;
    return count;
  };
}

const counter = makeCounter();

console.log(counter()); // 1
console.log(counter()); // 2

Why does this work?

Even though makeCounter has already run and finished, the inner function still has access to the count variable. That’s a closure in action!


🧩 How closures work

To understand closures, you just need to know:

  • Every time a function is created, it remembers the variables in its surrounding scope.
  • This memory is kept alive as long as the inner function is still being used.

Closures "close over" the variables they need—hence the name.


🚀 Why are closures useful?

Closures are powerful for many reasons:

✅ Data privacy

You can use closures to hide private variables:

function createSecret() {
  const secret = '🌟 Top secret';

  return {
    getSecret: () => secret
  };
}

const mySecret = createSecret();
console.log(mySecret.getSecret()); // "🌟 Top secret"

No one can change secret from the outside. It’s safely tucked inside the closure.


🔄 Preserving state

Closures help maintain state between function calls, like our makeCounter example.

This is useful in:

  • Event handlers
  • Functional programming
  • React hooks (they often rely on closures!)

🛠️ Function factories

You can create functions that are customized with closures:

function greet(name) {
  return function (message) {
    return `Hi ${name}, ${message}`;
  };
}

const greetCamila = greet('Camila');
console.log(greetCamila('welcome to the team!')); // "Hi Camila, welcome to the team!"


⚠️ Gotchas

Closures can be tricky when used inside loops:

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1000);
}
// Output: 3 3 3

To fix it, use let instead of var:

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

let creates a new binding for each iteration, so each function remembers the correct value.


✅ Quick recap

  • ✅ A closure is a function that remembers variables from its outer scope.
  • ✅ Use closures for state, data privacy, and custom function behavior.
  • ✅ Be mindful of loops and scope when using closures.

🧠 Final thoughts

Closures are one of the key ideas behind JavaScript’s flexibility. Once you get comfortable with them, you’ll start seeing them everywhere in callbacks, timers, React, and more.

You don’t need to master all the theory to use closures well just remember:

If a function can access variables from outside itself, and keep using them later, that’s a closure.

Closures = memory + functions. Simple as that.