The Module Pattern (IIFE + Closure)
HardThe 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}89const 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