🔒 Singleton — One Instance to Rule Them All
Category: general / design-patterns
Difficulty: medium
The Singleton pattern ensures a class has only one instance and provides a global point of access to it. In JavaScript, it's commonly used for configuration managers, logging services, caches, and state stores. 1️⃣ Core Idea [code example] Guarantee : only one object exists, and it’s easily accessible across the codebase. 2️⃣ Typical Front‑End Use‑Cases Why Singleton? Global access in any component. Analytics / Logging Client One source of truth for dark‑/light mode state. Event Bus 3️⃣ Implementing Singleton in JavaScript 3.1 ES Module Pattern (Simplest) [code example] 🤔 Why it works: ES modules are singletons by spec —imported once, cached forever. 3.2 Lazy Initialization Class [code example] 3.3 Factory‑Wrapped Singleton (Test‑Friendly) [code example] 3.4 Classic Closure-Based Singleton In a singleton design pattern, only one object is created for each interface (class or function), and the same object is returned every time the function or class is invoked. This pattern is especially useful in scenarios where only one object is needed to coordinate actions across the system — such as a notification manager, database connection, or event dispatcher. [code example] ✅ This pattern uses a private variable (<span>instance</span>) enclosed within an IIFE (Immediately Invoked Function Expression) to ensure that the <span>createInstance</span> function is only called once. 4️⃣ Pros & Cons ⚠️ Drawbacks Hidden global -> hard to trace dependencies Resource efficiency (one socket) Tight coupling: swapping impl is harder Controlled access (centralised) Rule of Thumb: If the object holds stateless functions , prefer pure modules. Use Singleton only for stateful shared resources . 5️⃣ Testing Strategies Factory Wrapper: As shown above, expose a getInstance() function and allow tests to inject a mock before first call. Module Mocking: In Jest/Vitest, jest.mock('./analytics', () => ({ analytics: mockObj })). Reset Hooks: Provide resetForTests() exported only in non‑prod builds ...