The Module Pattern in JavaScript is a design pattern that allows for the encapsulation of private variables and functions, exposing only a public interface. It’s a way to create private and public sections in a module. This pattern is particularly useful for organizing code into reusable, maintainable packages with clear separation of concerns.
Before the introduction of ES6 modules (import
/export
syntax), the Module Pattern was implemented using immediately invoked function expressions (IIFE) and closures. Here’s a classic example of the Module Pattern using an IIFE to create a simple calculator module.
Example: Calculator Module
Step 1: Define the Module
The calculator module will have private methods for addition, subtraction, and a public API that exposes these methods.
var CalculatorModule = (function() {
// Private variables and functions
var _data = { number: 0 };
function _add(x) {
_data.number += x;
return _data.number;
}
function _subtract(x) {
_data.number -= x;
return _data.number;
}
// Public API
return {
add: function(x) {
return _add(x);
},
subtract: function(x) {
return _subtract(x);
},
getValue: function() {
return _data.number;
}
};
})();
Step 2: Use the Module
With the module defined, you can now use its public API to perform operations. The internal state of the module is maintained across calls, but it’s not directly accessible from the outside.
console.log(CalculatorModule.getValue()); // 0
CalculatorModule.add(5);
console.log(CalculatorModule.getValue()); // 5
CalculatorModule.subtract(2);
console.log(CalculatorModule.getValue()); // 3
In this example, CalculatorModule
is an IIFE that returns an object. This object represents the module’s public API, exposing the add
, subtract
, and getValue
functions. The _add
and _subtract
functions, along with the _data
variable, are private to the module. They are not accessible from the outside, thus encapsulating the module’s state and behavior. The getValue
method is public and allows external code to read the current state without being able to directly modify it.
This pattern was widely used in JavaScript to emulate the concept of classes before ES6 introduced the class
keyword and modules. It’s a powerful way to create encapsulated pieces of code that interact with the rest of your application in a controlled manner.