There are scenarios in which only one instance of the specific class should ever exist, and that leads to Singleton Pattern.
The simplest singleton in JavaScript is an object literal; it provides a quick and cheap way to create a unique object:
const singleton = { foo(): void { console.log('bar'); } };
But sometimes we might want private variables:
const singleton = (() => { let bar = 'bar'; return { foo(): void { console.log(bar); } }; })();
Or we want to take the advantage of an anonymous constructor function or class expression in ES6:
const singleton = new class { private _bar = 'bar'; foo(): void { console.log(this._bar); } } ();
However, it is possible to have the requirements for creating new instances of "singletons" sometimes. Thus a normal class will still be helpful:
class Singleton { bar = 'bar'; foo(): void { console.log(bar); } private static _default: Singleton; static get default(): Singleton { if (!Singleton._default) { Singleton._default = new Singleton(); } return Singleton._default; } }
Another benefit brought by this approach is lazy initialization: the object only gets initialized when it gets accessed the first time.
Sometimes we might want to get "singletons" based on certain conditions. For example, every country usually has only one capital city, thus a capital city could be treated as a singleton under the scope of the specific country.
The condition could also be the result of context rather than explicit arguments. Assuming we have a class Environment
and its derived classes, WindowsEnvironment
and UnixEnvironment
, we would like to access the correct environment singleton across platforms by using Environment.default
and apparently, a selection could be made by the default
getter.
For more complex scenarios, we might want a registration-based implementation to make it extendable.
18.224.68.28