Singleton pattern in ES20XX
Or the like…
Singleton are really bad, I mean, not really needed in JavaScript.
That being said, you can find plenty of arguments on the topic often embellished with nice Java snippets.
The point here is not to give an opinion on why you should or should not be using this pattern but instead aggregate some ways of implementing it in ES2015 and beyond. Keep in mind that this is a just a tool and it is up to you to decide whether you want/need to use it or not in your application.
Use the following at your own risk.
Object {}
First let’s have a look at the why it is not needed side: here I can only quote one authority of the JavaScript community, Axel Rauschmayer:
The singleton pattern has been invented for class-based languages to help them implement components. […] In such languages, you cannot directly create the component object, you need a class to do so. [JavaScript] lets you directly create objects (being one of the few programming languages that allow you to do so) and there is no trickery necessary.
Using bare objects in ES6 will result in the following chunk:
This is the most straightforward way to implement this pattern. However as previously stated, the singleton pattern makes more sense with classes.
Module instance
A solution with ES6 is to use an instance of a class scoped to a module.
Either by using the new operator inside the module and export it as default:
Or by creating a null instance variable scoped to the module and assigning the this keyword inside the class constructor to it. When the constructor is called, it will:
- check the instance existence and assign this to it if it is null
- return the unique instance (the first created)
There are some drawbacks though:
Implementation 1: if you want to use a static method, you will have to use the constructor property of the exported instance.
Implementation 2: if you try to instantiate the class several times, no error will be thrown.
Ensure singularity
Via the use of Symbol and the SingletonEnforcer pattern from AS3…
…or by preventing multiple instantiation in the class constructor:
Again, some drawbacks here:
Implementation 3: as in the object implementation, you will have to get an .instance through a static getter.
Implementation 4: getter/setters are not accessible directly since no instance is created. You have to rely on static methods and properties.
Conclusion
This article is only the result of a small exploration about singletons in ES6 and probably lacks some in depth tests (feel free to correct if anything is wrong). Each of the solutions have advantages and drawbacks but at the end of the day it is probably a matter of taste/style to choose the one you need.
PS: some @decorators implementations are already available.