How to make a singleton in javascript
Singleton is one of the most common and easiest design pattern. In fact, a lot of designs are wrong just because the developer didn’t know about singletons and design patterns (I could have said : a lot of my designs were wrong just because I didn’t know about singletons and design patterns).
I was looking at the first three results for singleton javascript on Google and I was more than deceived by what they had to tell us. That’s why I write this article.
What is a singleton class?
A singleton is when your application needs to use just one instance of an object to centralize your access to it. Example, I have a list of cat names that can be used in various functions of an application. Sometimes, names are added or removed. I could use a global variable to the page containing the list. The problems are :
- It’s a global variable (global variables are bad).
- I don’t know when the list is created or initialized.
- If you reuse your class in another project, you will always need to define a global variable and instance it correctly.
- It’s ugly.
If I use a singleton pattern, the advantages are :
- The object is always correctly created.
- You don’t have to ask yourself questions about the state of the list or whatever. It just works!
- Another programmer can recognize the singleton pattern thus making it easier for him to work.
How to write a singleton class
Before writing a singleton, you need to know about creating objects and static functions.
-
// I create the class
-
function CatNames() {
-
this.names = new Array(); // The array that will contain the names
-
}
-
-
CatNames.instance = null; // Will contain the one and only instance of the class
-
-
// This function ensures that I always use the same instance of the object
-
CatNames.getInstance = function() {
-
if (CatNames.instance == null) {
-
CatNames.instance = new CatNames();
-
}
-
-
return CatNames.instance;
-
}
-
-
// Function to add a cat name
-
CatNames.prototype.add = function(catName) {
-
this.names.push(catName);
-
}
-
-
// Function to remove the last cat name
-
CatNames.prototype.removeLast = function() {
-
return this.names.pop();
-
}
-
-
// Function to alert all cat names
-
CatNames.prototype.alertAllCats = function() {
-
alert(this.names.join(","));
-
}
I use it in these functions.
-
function addThreeNames() {
-
// I use the one and only instance of the class (the magic of singletons)
-
var names = CatNames.getInstance();
-
-
names.add("Mistigri");
-
names.add("Bibi");
-
names.add("Gary");
-
}
-
-
function removeLastCat() {
-
// Once again, singleton is here
-
var names = CatNames.getInstance();
-
-
names.removeLast();
-
}
-
-
// I call the functions
-
// – no need for a global variable
-
// – no need to create the object and pass it as parameter
-
addThreeNames();
-
removeLastCat();
-
-
// Alert all cats
-
var names = CatNames.getInstance();
-
names.alertAllCats();
The downside of this technique
Yes I know, you can instantiate the singleton class if you want.
-
var catNames = new CatNames();
You know what? You’ll have to follow a simple rule : never instantiate a singleton class. Maybe we could use more techniques that would protect you from instantiating your own singleton class but it would be a waste of time and code.