SingletonLoading saved progress…

Singleton

Implement the Singleton pattern: a class that hands back the same instance every time it is constructed, no matter how many times you write new Singleton(). Think of it as the one front door to a building — there are many people who want to walk through it, but it is always the same door, and whatever you write on it everyone else can read. A logger, a database connection pool, or an app-wide config object are the usual real-world cases: you want exactly one, shared everywhere.

Signature

class Singleton {
  // Every `new` returns the SAME cached instance, not a fresh object.
  constructor(config?: object);

  // Returns the one shared instance, creating it on first call (lazy).
  static getInstance(config?: object): Singleton;

  // Clears the cached instance so the NEXT construction starts fresh.
  // Intended for test isolation.
  static reset(): void;

  // Read / write the shared state that every reference sees.
  set(key: string, value: unknown): this;
  get(key: string): unknown;
}

Examples

// Two constructions, one object.
const a = new Singleton();
const b = new Singleton();
a === b;            // → true
a.set('theme', 'dark');
b.get('theme');     // → 'dark'  (b IS a, so it sees the write)
// getInstance() returns that same shared object, and reset() starts over.
Singleton.getInstance() === new Singleton(); // → true

const first = new Singleton();
Singleton.reset();
const second = new Singleton();
first === second;   // → false  (reset cleared the cache; second is fresh)

Notes

  • Same instance, always. The core contract is new Singleton() === new Singleton(). State written through one reference must be visible through every other reference, because they are all literally the same object.
  • Initialization runs once. The constructor's one-time setup (allocating shared state, any side effect) happens on the first new only. Later new calls must not re-run it or reset existing state.
  • First arguments win. Decide how to treat new Singleton(config) when the instance already exists. Here, only the first construction's arguments are honored; later args are ignored, since the instance is already built.
  • getInstance() is lazy. Calling it before any new should create the instance on demand, then keep returning that same one.
  • reset() clears the cache, nothing else. It makes the next construction build a new instance; it does not reach into objects already handed out — old references keep their own state.
  • You don't need thread safety or modules. This is single-threaded JavaScript; no locks. Implementing it as a real ES module (where import caches the instance for you) is a valid pattern in practice but out of scope here — solve it with the class itself.
Loading editor…