Closures in JavaScript

📦 What are Closures?

A closure is created when a function "remembers" the variables from its lexical scope, even after that scope has been exited. This means an inner function has access to variables defined in its outer function — even after the outer function has finished executing. 🔁

Note

Closures enable powerful patterns like data privacy, function factories, and maintaining state between calls.

🧠 How It Works

Basic Closure Example

function outer() {
  let count = 0;

  function inner() {
    count++;
    console.log(count);
  }

  return inner;
}

const counter = outer();
counter(); // 1
counter(); // 2
counter(); // 3

Even though outer() has finished executing, the inner() function still has access to count. That’s a closure in action! 🔥

🔐 Use Case: Data Privacy

Closures help you encapsulate variables and prevent them from being accessed directly.

Private Counter using Closure

function createCounter() {
  let value = 0;

  return {
    increment() {
      value++;
      return value;
    },
    decrement() {
      value--;
      return value;
    }
  };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.value);       // undefined (private)

Note

🛡️ value is private to the createCounter scope — not directly accessible!

🛠 Closures with setTimeout

Closure preserves i value

function delayLog() {
  for (var i = 1; i <= 3; i++) {
    setTimeout(function () {
      console.log(i); // Will log 4 three times!
    }, i * 1000);
  }
}

delayLog();

To fix this with closure:

Fixed using IIFE

function delayLog() {
  for (var i = 1; i <= 3; i++) {
    (function (j) {
      setTimeout(function () {
        console.log(j); // Logs 1, 2, 3
      }, j * 1000);
    })(i);
  }
}

delayLog();

Note

💡 Closures remember the value of j at each iteration due to the IIFE (Immediately Invoked Function Expression).

🎯 Common Real-World Uses

  • ✅ Creating private variables (encapsulation)
  • 🔁 Memoization or caching
  • 📦 Factory functions
  • ⏱ setTimeout / async callback patterns

⚠️ Things to Watch Out For

  • ⛓ Unintended memory retention (especially in large apps)
  • 🧪 Overuse can lead to confusing, hard-to-debug code

📚 Summary

AspectDescription
DefinitionFunction + its lexical scope variables
UsePreserve state, data privacy, factories
RisksPossible memory leaks if misused

🔗 External References

>>“Closures are functions that remember the environment in which they were created.” – Kyle Simpson