According to Wikipedia:
...the singleton pattern is a design pattern that is used to restrict instantiation of a class to one object.
How does this apply to JavaScript? Well, in JavaScript there are no classes, just objects. So when you create a new object, there's no other object like it and the new object is already a singleton.
var obj = {
myprop: 'my value'
};
This is an example of creating a simple object in JavaScript using the object literal and it's also an example of a singleton.
Using new
The other question is how about if you want to use the Java-like syntax:
var obj = new Constructor();
This is more of classic-like syntax so the idea of a singleton here is that when you use new
to create several objects using the same constructor, you should only get one object.
var obj = new Constructor();
var obj2 = new Constructor();
alert(obj === obj2);
obj
is created only the first time the constructor is called, the second time (and the third, fourth, etc) the obj
created the first time is returned. How to achieve this in JavaScript?
Basically you need your Constructor
to cache the object instance this
once it's created and then pull this instance the second time it's called. You can cache the object instance:
- in a global variable - not recommended, general principle is that globals are bad, plus anyone can overwrite this global, even by accident;
- in a Constructor property - functions in JavaScript are objects, so they can have properties. You can have something like
Constructor.instance
and cache the object there. This is a nice clean solution with the only drawback that this property is accessible and code outside of yours might change it, so you lose the instance;
- wrap the instance in a closure
Let's take a look at an example implementation of the last option.
function Constructor() {
return Constructor.getInstance(this);
}
Constructor.getInstance = function(){
var instance;
return function(that) {
if (typeof instance === 'undefined') {
instance = that;
}
return instance;
}
}();
And a simpler new
Here's another way to do the class-like singleton. Secret sauce: using a closure to keep the reference to the single object and then rewrite the constructor.
function Single() {
var instance = this;
Single = function (){
return instance;
};
}
var my1 = new Single();
var my2 = new Single();
alert(my1 === my2)