Guarantee that a class has exactly one instance, and hand out one shared access point to it.
Some objects represent one real thing — the application's logging pipeline, a single database connection pool, a feature-flag cache. If any code can freely call `new` on that class, you can end up with two copies drifting out of sync: one thinks a flag is on, the other thinks it's off. Singleton closes that door by making construction private and routing every caller through one shared instance.
The class hides its constructor and exposes a static accessor. The first call builds the instance and stores it; every later call returns that same stored reference. Callers never see "new" — they only ever ask for the instance.
The instance is created on first access and cached on the class itself. Every subsequent call short-circuits straight to the cached object.
class ConfigStore {
static #instance;
#values;
constructor() {
if (ConfigStore.#instance) {
throw new Error("Use ConfigStore.getInstance() instead of new");
}
this.#values = { theme: "dark", retries: 3 };
}
static getInstance() {
if (!ConfigStore.#instance) {
ConfigStore.#instance = new ConfigStore();
}
return ConfigStore.#instance;
}
get(key) {
return this.#values[key];
}
set(key, value) {
this.#values[key] = value;
}
}
const a = ConfigStore.getInstance();
const b = ConfigStore.getInstance();
a.set("theme", "light");
console.log(b.get("theme")); // "light" — same instance
console.log(a === b); // true