A JavaScript Singleton, Part 2

There are two patterns I have seen most commonly for creating a singleton in JavaScript. The first, I call the “Literal Pattern” and it is the more successful. The second, I call the “Instance Pattern” and it is the less successful. There are others, many of which I shall not reference, except for one which I think is the most successful pattern of all.

I assume the reader is familiar with the mechanisms for creating objects in JavaScript. I shall refer to objects either as a “literal” or as an “instance” of a constructor, and I shall also assume that the developer will restrict herself to those mechanisms. I shall not preface with an exhaustive set of caveats: there are other objects as there are other patterns. The reader may be inclined to prefer them.

With the caveat that there are other patterns in Java, too, for creating a singleton, I reproduce a common one here.

Java

public class Singleton {
	private static volatile Singleton instance = null;
	private Singleton() { }
	public static Singleton getInstance() {
		if (instance == null) {
			synchronized (Singleton .class) {
				if (instance == null) {
					instance = new Singleton();
				}
			}
		}
		return instance;
	}
}

I cannot comment on whether or not this is the best pattern. I include it as a comparison with the patterns in JavaScript.

Literal Pattern

var Singleton	= (function () {
	var instance;
	function Constructor() { }
	return {
		getInstance: function getInstance() {
			if (!instance) {
				instance	= new Constructor();
			}
			return instance;
		}
	};
}());

Singleton is a literal with one privileged method named getInstance, which is an accessor to a private member, named instance, and a private constructor, named Constructor, declared inside a self-executing function. Invocation of Singleton assigns the operator this to the private member instance The accessor lazily permits instantiation of the constructor once.

Instance Pattern

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

Singleton is an instance of an anonymous constructor with one privileged method named getInstance, which is an accessor to a private member, named instance, and a private constructor, named Constructor. The accessor lazily permits instantiation of the constructor once.

The “Literal Pattern” employs both a literal and an instance in order to create a singleton. The “Instance Pattern” employs an instance of a constructor to give access to an instance of another constructor.

Both of these patterns make the constructor of the singleton private, but the privacy of the constructor is a problem and a weakness. Our developer, presented with this object, cannot easily establish of what it is an instance.

var singleton = Singleton.getInstance();

console.log(singleton instanceof Object);

This statement is true. But, this statement is true for any object, including any literal, or any function, or any array. Being true does not make it useful.

var singleton = Singleton.getInstance();

console.log(singleton instanceof Singleton);

In the “Literal Pattern” this statement generates a “TypeError” since “Singleton” is not a constructor. In the “Instance Pattern” this statement is false.

var singleton = Singleton.getInstance(),
	constructor = singleton.constructor; 

console.log(singleton instanceof constructor);

This statement is true. But, the “constructor” property must already be assigned to a variable with adequate scope for the comparison to be useful.

Our developer can examine the singleton for some signature which identifies it as our singleton but the “instanceof” operator reveals nothing useful unless she is willing to compare the object against other constructors to determine what instance it is not, and she cannot compare the “constructor” property of the object to the expected constructor unless she has already stored a reference to it elsewhere in her application.

This reveals a flaw in both patterns.

The constructor we are at pains to make private is not private: it is exposed as a property of the instance. Wherever she has the instance, she has the property and our developer can instantiate other objects with the constructor.

var singletonA = Singleton.getInstance(),
	singletonB = new singletonA.constructor(); 

console.log(singletonA === singletonB);

We cannot delete the constructor property from the instance and we cannot assign to the constructor property another value. Our developer can create innumerable instances of our constructor.

I appreciate the simplicity of the “Literal Pattern” but I wonder why it could not describe a literal with an accessor to another literal, lazily created and memoized, or whether the pattern could not simply reduce to describing a literal, eagerly created. The “Literal Pattern” reads like a transliteration into JavaScript from Java, which is not a strong criticism in and of itself, except that in JavaScript there are probably less verbose and more performant formulations for the same result, and this formulation does not entirely succeed in creating an object that can only be instantiated once.

The formulation of the “Instance Pattern” makes obscure something that should be more obvious, which I have already mentioned: it employs two constructors. Ironically, both constructors create a singleton, if we accept that the formulation creates a singleton at all; and if we do not accept it, then both constructors fail to create a singleton for the same reason as each other, and they fail for the same reason as the “Literal Pattern”: this formulation does not entirely succeed in creating an object that can only be instantiated once, either.

Encapsulation Pattern

var Singleton = (function () {
	var instance;
	return function Constructor() {
		if (!instance) {
			instance	= this;
		}
		return instance;
	};
}());

Singleton is declared as a variable and assigned the return value of a self-executing function. A private member, named instance, and a private constructor, named Constructor, are declared within that self-executing function: Constructor is the return value. Invocation of constructor Singleton examines member instance and if it evaluates truthy false then operator this is assigned to instance; instance is the return value.

This pattern exploits a feature of JavaScript constructors. When invoked, the return value of a constructor is an instance of that constructor unless another object is returned. A privileged accessor on another object to a private constructor is unnecessary. We can provide a constructor to our developer and she can invoke that constructor whenever she needs to, but it will only ever return the same instance. That instance is a singleton.

var singletonA = new Singleton(),
	singletonB = new Singleton(),
	singletonC = new singletonA.constructor(), 
	singletonD = new singletonB.constructor();

console.log(singletonA === singletonB);
console.log(singletonB === singletonC);
console.log(singletonC === singletonD);

That formulation of the “Encapsulation Patter” will lint but more compact formulations shall not.

Encapsulation Pattern

Ternary Operator

var Singleton = (function () {
	var instance;
	return function Constructor() {
		return (instance) ? instance : (instance = this);
	};
}());

The condition evaluates truthiness rather than falsiness.

Encapsulation Pattern

Default Operator

var Singleton = (function () {
	var instance;
	return function Constructor() {
		return instance || (instance = this);
	};
}());

The condition collapses further.

This pattern is rather a formulation for a singleton than the formulation and the reader may have requirements that are not captured here: yet since Singleton is a constructor it behaves as any other, and an instance of it behaves as any other, so anything that can be done with a constructor or an instance can be done with the "Encapsulation Pattern".

Advertisements

A JavaScript Singleton, Part 1

Douglas Crockford still has the simplest, most elegant explanation of public, private and privileged methods and members in JavaScript I have read (and his article also contains, as an aside, a similarly straightforward explanation of a closure).

I assume that the reader is familiar with objects, closures and prototypal inheritance in JavaScript, but I reproduce Crockford’s patterns here, with some minor alterations for clarity outside the context of his article.

Public

function Constructor() {
	this.publicMember = true;
}
Constructor.prototype.publicMethod = function publicMethod() { };

Private

function Constructor() {
	var privateMember = true;
	function privateMethod() { }
}

Privileged

function Constructor() {
	this.privilegedMethod = function privilegedMethod() { };
}

Public members can be created inside or outside the constructor, but public methods should be created outside, via the prototype.

Private members and methods can only be created inside the constructor.

Privileged methods can only be created inside the constructor: they are privileged because they are created as though private but exposed as though public, and so retain access to other private members and methods. Public methods do not have the same access, and private methods are not exposed.

Static members are harder to create. Several descriptions of static members I have read describe nothing more than private members, or public members, or private members assigned to public properties: which is to say, whatever they are, they are not static. They may be better described as default members, assigned to the instance when the constructor is invoked, but not shared across instances.

A static member can be created by exploiting closures, created within a self-executing function.

var Constructor = (function () {
	var staticMember = 0;
	function privilegedMethod() {
		return staticMember;
	}
	return function Constructor() {
		this.privilegedMethod = privilegedMethod;
	};
}()),
	c1 = new Constructor(),
	c2 = new Constructor(),
	c3 = new Constructor();

console.log(c1.privilegedMethod());
console.log(c2.privilegedMethod());
console.log(c3.privilegedMethod());

Creating three instances of Constructor and executing privilegedMethod on each of them will, unsurprisingly, return the value 0 to the caller at each call.

Demonstrating that staticMember is, indeed, static requires privilegedMethod to modify its value.

var Constructor = (function () {
	var staticMember = 0;
	function privilegedMethod() {
		return ++staticMember;
	}
	return function Constructor() {
		this.privilegedMethod = privilegedMethod;
	};
}()),
	c1 = new Constructor(),
	c2 = new Constructor(),
	c3 = new Constructor();

console.log(c1.privilegedMethod());
console.log(c2.privilegedMethod());
console.log(c3.privilegedMethod());

Creating three instances of Constructor and executing privilegedMethod on each instance will increment the value of staticMember.

A Singleton can be created from these components.