Closures Explained in minutes (🎒 Backpack Analogy)

Ever wondered why some functions “remember” things even after they should’ve been forgotten?

Like:

“How does this function still know that variable?!” 🤯

Congratulations — you just met one of JavaScript’s most powerful (and confusing) features:

Closures

Let’s break it down super simply. No CS degree needed.

🎒 Think of a Function as a Person with a Backpack

When a function runs, it’s like a person going on a trip.

Before they leave, they pack a backpack with everything they might need:

  • Variables from their current location
  • Variables from their parent’s house (outer function)
  • Even grandparents’ stuff if needed

That backpack? That’s a closure.

The function carries it everywhere, even after leaving home.

Example: Leaving Home But Keeping Memories

function parent() {
  const secret = "🔑 Secret key";

  function child() {
    console.log(secret); // Child still has access!
  }

  return child;
}

const myFunction = parent();
myFunction(); // Output: 🔑 Secret key

What just happened?

  1. parent() created a variable called secret
  2. parent() returned the child function
  3. Even though parent() finished running, child still remembers secret!

Why? Because child packed it in its backpack (closure) before leaving home.

Real-World Example: A Counter

function createCounter() {
  let count = 0; // Private variable in the backpack

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

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

Why is this useful?

  • count is private — you can’t access it directly
  • Only the functions inside the closure can modify it
  • It’s like data protection built into JavaScript!

Another Way to Think About It

Concept Analogy
Outer function Your home
Inner function You leaving home
Variables Stuff you might need
Closure Your backpack
Returned function You at your new location, still with your backpack

Try This in the Console

function makeGreeting(name) {
  const greeting = `Hello, ${name}!`;

  return function() {
    console.log(greeting);
  };
}

const greetAlice = makeGreeting("Alice");
const greetBob = makeGreeting("Bob");

greetAlice(); // Hello, Alice!
greetBob();   // Hello, Bob!

Why does this work?

  • Each time you call makeGreeting(), it creates a new closure
  • greetAlice has its own backpack with “Alice”
  • greetBob has its own backpack with “Bob”
  • They don’t interfere with each other!

Common Pitfall: Loop Problem

This is where beginners get confused:

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

Why?

  • All three functions share the same i
  • By the time they run, i is already 3!

Fix #1: Use let instead of var

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

let creates a new closure for each iteration!

Fix #2: Create a closure manually

for (var i = 0; i < 3; i++) {
  (function(num) {
    setTimeout(function() {
      console.log(num);
    }, 1000);
  })(i);
}
// Output: 0, 1, 2 ✅

When Are Closures Useful?

  • Private variables (like our counter example)
  • Factory functions (creating multiple instances)
  • Event handlers (remembering context)
  • Callbacks (preserving state)
  • Module pattern (organizing code)

TL;DR

Concept Meaning
Closure Function’s backpack of variables
Outer function Home where you pack stuff
Inner function You with the backpack
Variables Items in the backpack
Scope What you can access

Final Thought

Closures aren’t magic — they’re just functions remembering where they came from.

Every function in JavaScript has a built-in backpack.

It automatically packs variables from its surroundings.

That backpack goes wherever the function goes.

Once you understand that, closures stop being confusing and start being powerful.

Got questions?

Drop them in the comments! I love explaining the “why” behind the weird JavaScript behaviors we all encounter.

Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post

From NASA to $100M ARR: Adam Markowitz on scaling Drata

Related Posts