JavaScript | Tips

Object-Oriented JavaScript Tip: Implementing the Singleton Pattern

The Singleton design pattern is a development approach that ensures only a single instance of a particular class is available in a system. Imagine building the game of chess, you would only want there to be one instance of the board floating around—say an instance of a class called ChessBoard. The Singleton pattern ensures that there will only ever be one ChessBoard object available in your game.

Often the implementation of a Singleton looks something like this:

function Singleton()
{
}
 
Singleton.getInstance = function( )
{
	if (Singleton.instance == undefined) Singleton.instance = new Singleton();
	return Singleton.instance;
}

However, this is a port to JavaScript from other languages and it doesn’t offer a very robust implementation of the Singleton. For example, this design relies on calling Singleton.getInstance() to retrieve the single instance. However, nothing prevents calling…

var instance1 = new Singleton();
var instance2 = new Singleton();
alert( instance1 == instance2 ); // outputs false because these are two object instances

…to create two instances, defeating the pattern. A better approach is to encapsulate the Singleton constructor function in a variable and return a reference to the function rather than the instance, and then provide access to the instance via a getInstance method as above.

var Singleton = new function Singleton() 
{
	var instance = this;
	Singleton.getInstance = function()
	{
		return instance;
	}
}

In this case, the code shown earlier does not break the pattern:

var instance1 = new Singleton();
var instance2 = new Singleton();
alert( instance1 == instance2 ); // outputs true because these refer to the same constructor function

However, this just prevents circumvention of the pattern, the same object instance has not yet been retrieved. To do this the static getInstance() method is called on the constructor reference variable.

var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();
alert( instance1 == instance2 ); // outputs true because these refer to the same object instance

Additionally, a toString method, as well as static and instance methods (though both are functionally identically in this case since there’s only one instance available) can be built into the Singleton definition, like so:

var Singleton = new function Singleton() 
{
	var instance = this;
	Singleton.getInstance = function()
	{
		return instance;
	}
	this.toString = function()
	{
		return "[object Singleton]";
	}
 
	this.instanceMethod = function()
	{
		alert( "instance method called!" );		
	}
 
	Singleton.staticMethod = function()
	{
		alert( "static method called!" );
	}
	return Singleton;
}

Try these out:

Singleton.staticMethod();
Singleton.getInstance().instanceMethod();

Since JavaScript is a prototype-based language (not actually having classes), additional functionality can be added through the Singleton’s prototype, as in:

Singleton.prototype.custFunct = function(){ alert( "A custom method" ); } // add instance method
Singleton.getInstance().custFunct(); // call new instance method