Friday, July 31, 2009

JavaScript Singletons

JavaScript singletons are relatively simple to create. With two additional characters you can define your object as a singleton. I'll show how this is accomplished in a moment. In my prior JavaScript post I talked about why the module pattern was preferred for creating objects. Those objects were prototype-based and multiple instances were allowed. The following examples illustrate the preferred way to create singletons with the Module pattern. This should be your preferred creational pattern for creating JavaScript singletons.

Singleton Pattern Example #1:

/*
* Singleton counter example.
*/

var mySingletonCounter = function() {

/* private, static variables */
var count = 0;

return {
/* public methods */
increment: function (inc) {
alert('Adding ' + inc + ' to count.');
count += inc;
},

getCount: function() {
alert('The current count is ' + count);
return count;
}
};
}(); // <- These two parentheses define the object as a singleton. It assigns the result of invoking this function to mySingletonCounter.


To exercise the singleton, the button below will execute the following code:

mySingletonCounter.increment(2); mySingletonCounter.getCount();
Run Singleton Counter



Singleton Pattern Example #2:

/*
* Singleton data access example.
*/

var mySingletonData = function() {

/* private, static variables */
var data = {
1: "Harry Potter and the Philosopher's Stone",
2: "Harry Potter and the Chamber of Secrets",
3: "Harry Potter and the Prisoner of Azkaban"
};

return {
/* public methods */
getData: function() {
return data;
}
};
}();


Reference the singleton object in the following manner:

mySingletonData.getData()[2];
Run Singleton Data



Advantages:

  • It is extremely simple to declare a JavaScript object as a singleton. More dynamic languages are focusing on simplicity. For example, Groovy has recently provided the @Singleton transformation to simplify Singleton creation.
  • Improved run-time performance vs the prototype-based creational pattern.
  • You still leverage all the advantages that the module pattern provides.