Practical Closure Patterns

Med

Closures enable powerful patterns in JavaScript: data privacy (making variables private), function factories (creating functions with preset values), maintaining state in callbacks, and memoization (caching expensive computations). These patterns are used extensively in real-world code and frameworks.

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

  • Data privacy: closures hide variables from external access
  • Function factories: create specialized functions with preset configuration
  • State preservation: maintain state in event handlers and callbacks
  • Memoization: cache expensive function results
  • Module pattern: use IIFE + closure for encapsulation

Code Examples

Data Privacy (Private Variables)

function createBankAccount(initialBalance) {
  let balance = initialBalance;  // Private variable!
  
  return {
    deposit(amount) {
      if (amount > 0) {
        balance += amount;
        return balance;
      }
      return "Invalid amount";
    },
    withdraw(amount) {
      if (amount > 0 && amount <= balance) {
        balance -= amount;
        return balance;
      }
      return "Insufficient funds";
    },
    getBalance() {
      return balance;
    }
  };
}

const account = createBankAccount(100);
console.log(account.getBalance());  // 100
console.log(account.balance);       // undefined - private!
account.deposit(50);
console.log(account.getBalance());  // 150

The balance variable is hidden from external access - only methods in the closure can access it.

Function Factory

function makeMultiplier(factor) {
  // factor is captured in closure
  return function(number) {
    return number * factor;
  };
}

const double = makeMultiplier(2);
const triple = makeMultiplier(3);
const halve = makeMultiplier(0.5);

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

// Each function has its own factor in closure

Function factories create specialized functions with preset values captured in closure.

Once Function (Run Only Once)

function once(fn) {
  let ran = false;
  let result;
  
  return function(...args) {
    if (!ran) {
      ran = true;
      result = fn.apply(this, args);
    }
    return result;
  };
}

const initialize = once(() => {
  console.log("Initializing...");
  return "Setup complete";
});

console.log(initialize()); // "Initializing...", "Setup complete"
console.log(initialize()); // "Setup complete" (no log)
console.log(initialize()); // "Setup complete" (no log)

// The ran variable is preserved in closure

Closures can track state - in this case, whether a function has been called.

Memoization Pattern

function memoize(fn) {
  const cache = {};  // Private cache
  
  return function(...args) {
    const key = JSON.stringify(args);
    
    if (key in cache) {
      console.log("Cache hit!");
      return cache[key];
    }
    
    console.log("Computing...");
    const result = fn.apply(this, args);
    cache[key] = result;
    return result;
  };
}

const expensive = memoize((n) => {
  console.log("Heavy computation...");
  return n * n;
});

console.log(expensive(5));  // Computing..., Heavy..., 25
console.log(expensive(5));  // Cache hit!, 25 (instant!)

Closures maintain private cache to store expensive computation results.

Common Mistakes

  • Creating memory leaks by holding large objects in closures
  • Not realizing closure variables are shared (not copied)
  • Forgetting to clean up event listeners that use closures

Interview Tips

  • Give concrete examples: data privacy, memoization, once function
  • Explain the module pattern (IIFE + closure)
  • Know when closures might cause memory leaks
  • Show you understand practical applications