Understanding JavaScript Closures — The Secret Behind the Magic



This content originally appeared on DEV Community and was authored by Santan Sharma

What is a Closure?
A closure is when a function “remembers” the variables from the place where it was created — even after that place is gone.

In simpler terms:

A closure gives you access to an outer function’s scope from an inner function.

Why Should You Care?

  1. Closures are everywhere in JavaScript:
  2. They power callbacks and event handlers
  3. They’re behind the scenes in setTimeout, promises, and Angular zones
  4. They help you encapsulate data (like in OOP)
  5. They make function factories and private variables possible

Let’s Break It Down with a Real-Life Analogy
Imagine your local tea vendor (chaiwala) 🫖. You go there every day. You give your name and he remembers your order. Even after 3 days, he says:

“Bhaiya, adrak wali chai na? Theek hai.”_

How did he remember? Did you write it down? No.
He closed over your name and chai preference. That’s how closures work. 😄

function makeTea(type) {
  return function () {
    console.log(`Here is your ${type} tea ☕`);
  };
}

const gingerTea = makeTea("Ginger");
const greenTea = makeTea("Green");

gingerTea();  // Here is your Ginger tea ☕
greenTea();   // Here is your Green tea ☕

🧠 What’s happening here?

makeTea(“Ginger”) returns a new function
That function remembers type = “Ginger” even after makeTea has finished running
That memory is the closure

Real Use Case: Button Click in Angular or Vanilla JS
Let’s say you’re making a dashboard where clicking a button shows different messages. You want each button to “remember” its own message.

function setupButton(id, message) {
  document.getElementById(id).addEventListener('click', function () {
    alert(message);
  });
}

setupButton("btn1", "Dashboard loaded!");
setupButton("btn2", "Settings loaded!");

Each button now has its own closure. Without closures, all buttons would alert the same last message.

🧙 Fun Fact: Closures Make Data Private

You can use closures to simulate private variables just like in OOP.

function Counter() {
  let count = 0;
  return {
    increment: function () {
      count++;
      return count;
    },
    decrement: function () {
      count--;
      return count;
    }
  };
}

const counter = Counter();
console.log(counter.increment()); // 1
console.log(counter.decrement()); // 0

count is not accessible directly — only via the functions. A neat encapsulation trick!

Where People Get Confused

  1. Does a closure copy the variable?

    No, it remembers the reference to the variable.

  2. Can it keep many variables?

    Yes, any variables in its scope at creation are remembered.

  3. Will it cause memory leaks?

    Not usually. Modern engines manage it well unless you accidentally create long-lived references (like in DOM events).

** > Closures may sound intimidating, but they are a natural part of JavaScript — especially functional programming and frontend frameworks like Angular.**

If you understand closures, you understand how JavaScript thinks.

So next time someone talks about JavaScript being weird, just smile and say:

“It’s not weird. It’s just... closed over logic.”

🙌 Final Thought
If you liked this explanation and want more on things like async/await, this keyword, or Angular Observables in plain English — let me know! We can break the toughest nuts together 🧠🔧


This content originally appeared on DEV Community and was authored by Santan Sharma