The Module Pattern (IIFE + Closure)

Hard

The Module Pattern uses an IIFE (Immediately Invoked Function Expression) combined with closures to create encapsulated modules with private and public members. This was the standard way to create modules before ES6 modules. It provides true privacy - unlike ES6 classes where "private" fields are merely conventions.

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

  • IIFE creates a new scope that encapsulates private variables
  • Return an object with public methods (closures)
  • Private variables are truly private - no external access
  • Before ES6 modules, this was the standard pattern
  • Revealing Module Pattern: define all at top, return object at bottom

Code Examples

Basic Module Pattern

const counterModule = (function() {
  // Private variables
  let count = 0;
  const privateMethod = () => console.log("Private!");
  
  // Public API
  return {
    increment() {
      count++;
      return count;
    },
    decrement() {
      count--;
      return count;
    },
    getCount() {
      return count;
    }
  };
})();

console.log(counterModule.getCount());  // 0
counterModule.increment();
counterModule.increment();
console.log(counterModule.getCount());  // 2
console.log(counterModule.count);       // undefined (private!)

// The IIFE runs immediately, returns public API
// Private variables are hidden in closure

IIFE creates scope, returns object with methods that form closures over private variables.

Revealing Module Pattern

const myModule = (function() {
  // All declarations at the top
  let privateVar = 0;
  
  function privateMethod() {
    console.log("Private:", privateVar);
  }
  
  function publicMethod() {
    privateMethod();
  }
  
  function anotherPublic() {
    privateVar++;
  }
  
  // Reveal public API at the bottom
  return {
    doSomething: publicMethod,
    increment: anotherPublic,
    getValue: () => privateVar
  };
})();

myModule.doSomething();  // "Private: 0"
myModule.increment();
myModule.doSomething();  // "Private: 1"

Revealing pattern: define functions with descriptive names, then return object mapping public names to them.

Common Mistakes

  • Not using parentheses around function in IIFE
  • Trying to access private variables from outside
  • Forgetting that each IIFE call creates separate scope

Interview Tips

  • Know the IIFE syntax: (function() { ... })()
  • Understand the difference between Module Pattern and ES6 modules
  • Know that Module Pattern provides true privacy
  • Show the Revealing Module Pattern variant