What is a Closure?

Med

A closure is a function that has access to variables from its outer (enclosing) scope even after the outer function has returned. The closure "remembers" the environment in which it was created. This is possible because of lexical scoping - functions in JavaScript form closures. Understanding closures is fundamental to mastering JavaScript.

Interactive Visualization

CodeCreation Phase
1function outer() {
2 let x = 10;
3 function inner() {
4 return x;
5 }
6 return inner;
7}
8
9const fn = outer();
10fn(); // 10
Call Stack
Global EC
Variables:
fnundefined
Heap Memory
(empty)
Output
Global EC created - outer function is defined
1 / 6
Key Insight: A closure is formed when an inner function is returned from an outer function, maintaining access to the outer function's variables even after the outer function has completed.

Key Points

  • A closure is created when a function is defined inside another function
  • The inner function maintains access to outer scope variables
  • Variables are captured by reference, not by value
  • Closures exist even without explicit return (all inner functions are closures)
  • Lexical scope determines what variables a closure has access to

Code Examples

Simple Closure

function outer() {
  const message = "Hello from outer";
  
  function inner() {
    console.log(message); // Accesses outer variable
  }
  
  return inner;
}

const fn = outer();    // outer() finishes executing
fn();                  // "Hello from outer"

// inner() still has access to message!
// This is a closure.

The inner function maintains access to outer variables even after outer() has returned.

Closure Captures Reference

function createCounter() {
  let count = 0;
  
  return {
    increment() {
      count++;           // References outer count
      return count;
    },
    decrement() {
      count--;
      return count;
    },
    getValue() {
      return count;
    }
  };
}

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

// count persists between calls!

The returned object methods form closures over the count variable.

Every Function is a Closure

const globalVar = "I'm global";

function example() {
  console.log(globalVar); // Accesses global scope
}

example(); // "I'm global"

// Even this is technically a closure!
// It has access to variables in its lexical scope (global)

function outer() {
  const outerVar = "I'm outer";
  
  function inner() {
    console.log(outerVar); // Closure
    console.log(globalVar); // Also a closure
  }
  
  inner(); // Both are closures
}

outer();

Technically, every function in JavaScript is a closure because they all have access to their outer scope.

Common Mistakes

  • Thinking closures only happen with explicit returns
  • Not understanding that variables are captured by reference
  • Expecting closures to capture by value (like copies)

Interview Tips

  • Use the "backpack" or "backpack" metaphor
  • Explain that closures are formed at function definition, not execution
  • Mention that all functions in JS are technically closures
  • Be ready to trace what variables a closure has access to