What is the simplest/cleanest way to implement singleton pattern in JavaScript?
@CMS and @zzzzBov have both given wonderful answers, but just to add my own interpretation based on my having moved into heavy node.js development from PHP/Zend Framework where singleton patterns were common.
The following, comment-documented code is based on the following requirements:
My code is very similar to @zzzzBov's except I've added a prototype chain to the constructor and more comments that should help those coming from PHP or a similar language translate traditional OOP to Javascripts prototypical nature. It may not be the "simplest" but I believe it is the most proper.
// declare 'Singleton' as the returned value of a self-executing anonymous function
var Singleton = (function () {
"use strict";
// 'instance' and 'constructor' should not be availble in a "public" scope
// here they are "private", thus available only within
// the scope of the self-executing anonymous function
var _instance=null;
var _constructor = function (name) {
this.name = name || 'default';
}
// prototypes will be "public" methods available from the instance
_constructor.prototype.getName = function () {
return this.name;
}
// using the module pattern, return a static object
// which essentially is a list of "public static" methods
return {
// because getInstance is defined within the same scope
// it can access the "private" 'instance' and 'constructor' vars
getInstance:function (name) {
if (!_instance) {
console.log('creating'); // this should only happen once
_instance = new _constructor(name);
}
console.log('returning');
return _instance;
}
}
})(); // self execute
// ensure 'instance' and 'constructor' are unavailable
// outside the scope in which they were defined
// thus making them "private" and not "public"
console.log(typeof _instance); // undefined
console.log(typeof _constructor); // undefined
// assign instance to two different variables
var a = Singleton.getInstance('first');
var b = Singleton.getInstance('second'); // passing a name here does nothing because the single instance was already instantiated
// ensure 'a' and 'b' are truly equal
console.log(a === b); // true
console.log(a.getName()); // "first"
console.log(b.getName()); // also returns "first" because it's the same instance as 'a'
Note that technically, the self-executing anonymous function is itself a Singleton as demonstrated nicely in the code provided by @CMS. The only catch here is that it is not possible to modify the prototype chain of the constructor when the constructor itself is anonymous.
Keep in mind that to Javascript, the concepts of “public” and “private” do not apply as they do in PHP or Java. But we have achieved the same effect by leveraging Javascript’s rules of functional scope availability.
can I put my 5 coins. I have a constructor function, ex.
var A = function(arg1){
this.arg1 = arg1
};
What I need to do is just every object created by this CF will be same.
var X = function(){
var instance = {};
return function(){ return instance; }
}();
test
var x1 = new X();
var x2 = new X();
console.log(x1 === x2)
I'm not sure I agree with the module pattern being used as a replacement for a singleton pattern. I've often seen singletons used and abused in places where they're wholly unnecessary, and I'm sure the module pattern fills many gaps where programmers would otherwise use a singleton, however the module pattern is not a singleton.
var foo = (function () {
"use strict";
function aPrivateFunction() {}
return { aPublicFunction: function () {...}, ... };
}());
Everything initialized in the module pattern happens when Foo
is declared. Additionally, the module pattern can be used to initialize a constructor, which could then be instantiated multiple times. While the module pattern is the right tool for many jobs, it's not equivalent to a singleton.
var Foo = function () {
"use strict";
if (Foo._instance) {
//this allows the constructor to be called multiple times
//and refer to the same instance. Another option is to
//throw an error.
return Foo._instance;
}
Foo._instance = this;
//Foo initialization code
};
Foo.getInstance = function () {
"use strict";
return Foo._instance || new Foo();
}
long form, using module pattern
var Foo = (function () {
"use strict";
var instance; //prevent modification of "instance" variable
function Singleton() {
if (instance) {
return instance;
}
instance = this;
//Singleton initialization code
}
//instance accessor
Singleton.getInstance = function () {
return instance || new Singleton();
}
return Singleton;
}());
In both versions of the Singleton pattern that I've provided, the constructor itself can be used as the accessor:
var a,
b;
a = new Foo(); //constructor initialization happens here
b = new Foo();
console.log(a === b); //true
If you don't feel comfortable using the constructor this way, you can throw an error in the if (instance)
statement, and stick to using the long form:
var a,
b;
a = Foo.getInstance(); //constructor initialization happens here
b = Foo.getInstance();
console.log(a === b); //true
I should also mention that the singleton pattern fits well with the implicit constructor function pattern:
function Foo() {
if (Foo._instance) {
return Foo._instance;
}
//if the function wasn't called as a constructor,
//call it as a constructor and return the result
if (!(this instanceof Foo)) {
return new Foo();
}
Foo._instance = this;
}
var f = new Foo(); //calls Foo as a constructor
-or-
var f = Foo(); //also calls Foo as a constructor
If you want to use classes:
class Singleton {
constructor(name, age) {
this.name = name;
this.age = age;
if(this.constructor.instance)
return this.constructor.instance;
this.constructor.instance = this;
}
}
let x = new Singleton('s',1);
let y = new Singleton('k',2);
Output for the above will be:
console.log(x.name,x.age,y.name,y.age) // s 1 s 1
Another way of writing Singleton using function
function AnotherSingleton (name,age) {
this.name = name;
this.age = age;
if(this.constructor.instance)
return this.constructor.instance;
this.constructor.instance = this;
}
let a = new AnotherSingleton('s',1);
let b = new AnotherSingleton('k',2);
Output for the above will be:
console.log(a.name,a.age,b.name,b.age)// s 1 s 1
Module pattern: in "more readable style". You can see easily which methods are publics and which ones are privates
var module = (function(_name){
/*Local Methods & Values*/
var _local = {
name : _name,
flags : {
init : false
}
}
function init(){
_local.flags.init = true;
}
function imaprivatemethod(){
alert("hi im a private method");
}
/*Public Methods & variables*/
var $r = {}; //this object will hold all public methods.
$r.methdo1 = function(){
console.log("method1 call it");
}
$r.method2 = function(){
imaprivatemethod(); //calling private method
}
$r.init = function(){
inti(); //making init public in case you want to init manually and not automatically
}
init(); //automatically calling init method
return $r; //returning all publics methods
})("module");
now you can use publics methods like
module.method2(); //-> I'm calling a private method over a public method alert("hi im a private method")
http://jsfiddle.net/ncubica/xMwS9/
function Unicode()
{
var i = 0, unicode = {}, zero_padding = "0000", max = 9999;
//Loop through code points
while (i < max) {
//Convert decimal to hex value, find the character, then pad zeroes to the codepoint
unicode[String.fromCharCode(parseInt(i, 16))] = ("u" + zero_padding + i).substr(-4);
i = i + 1;
}
//Replace this function with the resulting lookup table
Unicode = unicode;
}
//Usage
Unicode();
//Lookup
Unicode["%"]; //returns 0025