DevPath · Learn to code ESPTEN

Scope, hoisting and closures

Closures

A closure is a function that remembers where it was born

Here comes the star idea of this module, and it's not as hard as it sounds.

Picture every function, the moment it's born, grabbing a backpack with the variables it had on hand right then. Even if the function travels off to another part of the program and its birthplace no longer exists, it keeps carrying that backpack and can still look inside. That's a closure: a function that remembers the world where it was born.

Why should you care? Because closures power things you use every day: counters, unique ID generators, private data nobody can touch from outside, even React hooks. Nail this and half of modern libraries stop looking like magic.

Classic example: a counter with memory

function makeCounter() {
  let count = 0;          // "private" variable
  return function () {
    count = count + 1;    // remembers and modifies count
    return count;
  };
}

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

The count variable does not exist outside makeCounter: nobody can read it or change it from outside. But the returned function carries it in its backpack, so it remembers it and updates it between calls. You just created a piece of private data.

Each closure has its own backpack

const a = makeCounter();
const b = makeCounter();
console.log(a()); // 1
console.log(a()); // 2
console.log(b()); // 1 (independent from a)

Each call to makeCounter hands out a fresh backpack, so a and b never step on each other. It's like giving every user their own safe.

Why do they matter in the real world?

Once the backpack clicks, you've unlocked one of JavaScript's superpowers.

Examples

The backpack holds the greeting: hello and bye each remember their own

function makeGreeting(greeting) {
  return function (name) {
    return greeting + ", " + name;
  };
}
const hello = makeGreeting("Hello");
const bye = makeGreeting("Goodbye");
console.log(hello("Ann"));  // "Hello, Ann"
console.log(bye("Ann"));    // "Goodbye, Ann"
Put this into practice

DevPath is a hands-on course: you read the theory here; in the app you put it into practice with exercises that really run, offline.

Start free in the app →
← HoistingView the module →