DEV Community

SAURAV KUMAR
SAURAV KUMAR

Posted on

🧠 How Do Closures Work in JavaScript?

Explained in Simple Words (with Code Examples & Interview Tips)

When I first started learning JavaScript, the word closure sounded scary.

Later I realised closures are just functions that remember things — nothing magical, only useful.

This article explains closures in plain English, with small code examples and a short interview-friendly answer you can use. Let’s keep it simple and practical.


🧩 What Is a Closure?

A closure is when a function remembers and uses variables from its outer (parent) function — even after the outer function has finished running.

Think of it like a backpack 🎒: when a function is created, it carries its surrounding variables inside that backpack. Even if the parent function returns, the inner function still has access to those items in the backpack.


💡 Very Simple Example

function outerFunction() {
  let count = 0;

  function innerFunction() {
    count++;
    console.log("Count is:", count);
  }

  return innerFunction;
}

const counter = outerFunction();

counter(); // Count is: 1
counter(); // Count is: 2
counter(); // Count is: 3

Enter fullscreen mode Exit fullscreen mode

Why this shows a closure:

innerFunction keeps access to count even after outerFunction has finished. That remembered access is a closure.


🧠 Step-by-step: What’s Happening?

  1. Call outerFunction() → it creates a local variable count = 0.
  2. Define innerFunction() inside outerFunction().
  3. Return innerFunction from outerFunction.
  4. Even though outerFunction finishes, innerFunction still remembers count.
  5. Each call to counter() updates the same count stored in the closure.

🔐 Practical Use: Private Data (Counter Module)

Closures help you hide data (make it private) and expose only controlled methods.

function createCounter() {
  let count = 0; // private

  return {
    increment() {
      count++;
      console.log("Count:", count);
    },
    decrement() {
      count--;
      console.log("Count:", count);
    },
    getCount() {
      return count;
    }
  };
}

const counter = createCounter();
counter.increment(); // Count: 1
counter.increment(); // Count: 2
console.log(counter.getCount()); // 2
// direct access like counter.count → undefined

Enter fullscreen mode Exit fullscreen mode

Benefit: count cannot be changed except via the provided methods. This pattern avoids global variables and accidental mutations.


⏰ Closures with Async Code

Closures work perfectly with timers, promises, and callbacks.

function greetUser(name) {
  setTimeout(function () {
    console.log("Hello, " + name);
  }, 1000);
}

greetUser("Saurav"); // After 1s: Hello, Saurav

Enter fullscreen mode Exit fullscreen mode

Even after greetUser returns, the timeout callback remembers name because of the closure.


⚙️ Function Factories (Another Useful Pattern)

Closures can produce customised functions.

function multiplyBy(factor) {
  return function (number) {
    return number * factor;
  };
}

const double = multiplyBy(2);
const triple = multiplyBy(3);

console.log(double(5)); // 10
console.log(triple(5)); // 15

Enter fullscreen mode Exit fullscreen mode

Each returned function remembers its own factor. This is simple and powerful.


⚠️ Common Beginner Mistakes

  • Shared loop variable problem: Using var in loops with closures can be confusing. Prefer let or create new scopes.
  • Memory concerns: Closures keep references to outer variables; avoid holding large data unnecessarily.
  • Confusing scopes: Same variable names in inner and outer scopes shadow each other — be clear about where a variable is defined.

🚀 Where You See Closures in Real Code

  • React hooks (useState, useEffect) use closures under the hood.
  • Event handlers that access outer variables.
  • Module and factory patterns for encapsulation.
  • Currying and functional utilities.

🧠 Key Takeaway

A closure is simply an inner function that remembers variables from its outer scope.

Use closures to keep data private, remember state, and write modular code.


🎯 Bonus: How to Explain Closures in an Interview (with Example)

When an interviewer asks “What is a closure?” or “Explain closures in JavaScript”, keep your answer short and then show a tiny example.

Short answer (30–45 seconds)

A closure is when a function remembers the variables from its outer scope even after that outer function has finished executing. In other words, the inner function carries its lexical environment with it. Closures enable data privacy and stateful functions in JavaScript.

Follow-up: Quick example to show on the whiteboard or in code

function makeGreeter(name) {
  return function greet() {
    console.log("Hello, " + name);
  };
}

const greetSaurav = makeGreeter("Saurav");
greetSaurav(); // Hello, Saurav

Enter fullscreen mode Exit fullscreen mode

Explain while you show it:

  • makeGreeter creates a local name.
  • It returns greet, which uses name.
  • Even after makeGreeter returns, greet still remembers name — that’s a closure.

Common interview follow-ups & how to answer them

  • Q: Why is closure useful? A: For stateful functions and data privacy without globals. It helps implement modules, factories, and callbacks.
  • Q: Any pitfalls? A: If not careful, closures can unintentionally keep large objects alive, causing memory to be retained. Also, loop-variable capture mistakes can confuse results — use let to avoid it.
  • Q: Can you show a bug caused by closures? A: Yes — older code using var in loops with async callbacks captures the same variable. Show the fixed version using let or an IIFE.

Mini whiteboard challenge (simple coding task)

Task: Write a function makeCounter() that returns an object with increment and get methods. get returns the current count.

Solution to write quickly:

function makeCounter() {
  let count = 0;
  return {
    increment() { count++; },
    get() { return count; }
  };
}

const c = makeCounter();
c.increment();
console.log(c.get()); // 1

Enter fullscreen mode Exit fullscreen mode

Why this is a good interview answer:

  • Short, correct, and shows you understand closures and data privacy.
  • You can extend it (add decrement, validation) if asked.

👋 About Me

Hi, I'm Saurav Kumar — a Software Engineer passionate about building modern web and mobile apps using JavaScript, TypeScript, React, Next.js, and React Native.

I’m exploring how AI tools can speed up development,

and I share beginner-friendly tutorials to help others grow faster.

🔗 Connect with me:

LinkedIn — I share short developer insights and learning tips

GitHub — Explore my open-source projects and experiments

If you found this helpful, share it with a friend learning JavaScript — it might help them too.

Until next time, keep coding and keep learning 🚀

Top comments (0)