JavaScript (trước ES6) không có class/module built-in. Module Pattern dùng IIFE (Immediately Invoked Function Expression) + Closure để tạo scope private, expose public API qua object trả về.
Ví dụ: Quản lý người bỏ phiếu
<!DOCTYPE html>
<html>
<body>
<script>
const VoterModule = (function() {
// Private data & methods
const votersAge = [15, 50, 27, 17, 22, 87, 65, 45];
function calculateAverage() {
const total = votersAge.reduce((acc, age) => acc + age, 0);
return total / votersAge.length;
}
function getNotQualified() {
const notAdult = votersAge.filter(age => age < 18);
return `Người bỏ phiếu không đủ điều kiện (dưới 18 tuổi): ${notAdult.length}`;
}
// Public API
return {
getAverageAge: calculateAverage,
getNotQualifiedCount: getNotQualified,
// Không expose votersAge trực tiếp
};
})();
// Sử dụng
console.log(VoterModule.getNotQualifiedCount());
console.log('Tuổi trung bình:', VoterModule.getAverageAge());
// console.log(VoterModule.votersAge); // undefined - private
</script>
</body>
</html>
Yếu tố cốt lõi
- IIFE: Tạo scope mới, chạy ngay lập tức.
- Closure: Hàm bên trong nhớ biến ở scope ngoài (votersAge).
- Private: Biến/hàm không return ra ngoài → không truy cập được từ bên ngoài.
- Public: Object trả về chứa method cho phép truy cập an toàn.
So sánh với ES6 Modules
| Đặc điểm | Module Pattern (IIFE) | ES6 Modules (import/export) |
|---|---|---|
| Scope | Function scope | Module scope (file) |
| Loading | Sync, inline | Async, static analysis |
| Tree-shaking | Không | Có |
| Browser support | Mọi trình duyệt | Modern (cần bundler cho cũ) |
Khuyến nghị: Dùng ES6 Modules cho dự án mới. Module Pattern vẫn hữu ích cho legacy, plugin, hoặc namespace đơn giản.