On Initialising Constructors

Several years ago I worked on a project where the lead had established a pattern for constructors.

function Constructor() { }
Constructor.prototype.initialise = function () { /* initialisation */ }

I read this as being a pattern created by someone who came from another language to JavaScript and wondered, “where is main?”

Where, in the definition of their class, ought they put the initialisation?

You may have good reasons for deferring initialisation after instantiation, and consequently for separating initialisation from instantiation with a named method, but not if your every use of that pattern reduces to the statement:

(new Constructor()).initialise();

Why introduce a named method?

The constructor is the initialisation function!

function Constructor() { /* initialisation */ }

Instantiation reduces to:

new Constructor();

Unless the mechanism you’re creating requires the separation of instantiation from initialisation, or offers it as a feature, establishing a pattern which resembles it introduces uncertainty into your code.

Separating initialisation from the Constructor

You may want to separate initialisation from instantiation under particular circumstances.

Your library is published with several constructors available for use by developers, but you want to ensure that they can only use the constructor as a constructor, not as a function by omitting the “new” keyword.

function Constructor() { return (this instanceof Constructor) ? this : new Constructor(); }

By interrogating “this” you can determine whether execution is occurring in the context of an instance of the constructor itself, or in some other context. It’s that “some other context” which you want to prevent. It could be that the function is being invoked as a function, or it could be that the function is being invoked from a “call” to the function (with another object supplied as the context). Perhaps your code should throw an error?

The context of “this” is likely to be very important, with errors inevitable if it’s invalid.

function Constructor() {
	if (this instanceof Constructor) {
		this.prepareInstanceValues();
	} else {
		return new Constructor();
	}
}
Constructor.prototype.prepareInstanceValues = function () { };

You are confident that it’s appropriate for your library to invoke the constructor again, but this time with the “new” keyword, so that the return from any invocation is an instance of the constructor.

var instanceA = Constuctor(),
	instanceB = new Constructor();

console.log(instanceA instanceof Constructor);
console.log(instanceB instanceof Constructor);

A constructor can quickly start to look quite cluttered when initialisation steps are introduced. While the steps here are few, this constructor is already doing two very different things.

As far as possible the code should express the single responsibility principle.

Every method should contain only the discrete steps that are described by the method name: too broad, and your method performs too many separate steps; too narrow, and your method performs too few additional steps to justify even one additional description.

A method calling another method can increase readability, or it can decrease comprehension.

Do these steps make sense, as a group?

Are they called elsewhere, in the same order?

You want to guide the reader toward an understanding of the code but not at the expense of chasing method name after method name until they reach a single, lonely expression.

In the case of this constructor, I would rather communicate the decision made by the conditional “if” than elaborate the initialisation steps. I want to introduce an “initialise” method onto my constructor.

I’m going to assume that the initialisation steps are the methods I described earlier, assigned to the prototype of the constructor.

I could introduce an “initialise” method onto my constructor by assigning it to the prototype. I can write a test to ensure that it’s invoked and the initialisation steps are followed:

function Constructor() {
	this.initialise();
}
Constructor.prototype.initialise = function () { /* initialisation */ }

Alternatively, I could create an initialisation method inside the constructor, because I can write a test to ensure that the initialisation steps are followed, even though I don’t have access to the initialisation method itself:

function Constructor() {
	function initialise() { /* initialisation */ }
	initialise.call(this);
}

Alternatively, I could create an initialisation method outside the constructor, which ensures that the initialisation function isn’t recreated every time the constructor function is invoked:

function initialise() { /* initialisation */ }
function Constructor() {
	initialise.call(this);
}

If the constructor always calls “initialise”, one way or another, then I don’t gain anything of significance by assigning a method to the prototype. Generally, we might prefer that methods are public to maximise unit test coverage, but in this case, the “initialise” method is a surrogate for the constructor itself.

As before, unless the mechanism you’re creating requires the separation of instantiation from initialisation, or offers it as a feature, establishing a pattern which resembles it introduces uncertainty into your code.

Should a developer, implementing your library, call “initialise”, or not?

Would that call be destructive and can it be defended against? From trying to ensure that my function is always invoked as a constructor I am now trying to defend against repeated invocations of the “initialise” method. Goodness, now I need a property called “hasInitialised”. Should that be public or private? If it’s public, then developers implementing my library might override it. If it’s private, it may not be so easy to write a test.

Let’s step back.

I want to ensure that other developers can only use the constructor as a constructor, not as a function by omitting the “new” keyword. The constructor has some initialisation steps, and I want to move those steps into a distinct method so that the constructor reads cleanly, but I don’t want to make that method public because those steps are not overridable.

I’m going to put the initialisation method outside the constructor. Inside is fine, but it means that the function is created again whenever the constructor is invoked, which is unnecessary. I can isolate my constructor within a module with the Module Pattern to ensure that the initialisation method remains private.

var Constructor = (function () {
	function initialise() {
		this.prepareInstanceValues();
	}
	function Constructor() {
		if (this instanceof Constructor) {
			initialise.call(this);
		} else {
			return new Constructor();
		}
	}
	Constructor.prototype.prepareInstanceValues = function () { };
	return Constructor;
}());

A constructor can’t return anything besides an instance, except another instance. I can reduce this formulation to a ternary:

var Constructor = (function () {
	function initialise() {
		this.prepareInstanceValues();
	}
	function Constructor() {
		return (this instanceof Constructor) ? initialise.call(this) : new Constructor();
	}
	Constructor.prototype.prepareInstanceValues = function () { };
	return Constructor;
}());

Problems posed by reusing initialisation with other Constructors

With this pattern established, I can create a private, common class from which other classes inherit, and some public classes which reuse the same initialisation method.

var library = (function () {

	function CommonConstructor() { }
	CommonConstructor.prototype.prepareInstanceValues = function () { };

	function initialise() {
		this.prepareInstanceValues();
	}

	function ConstructorOne() {
		return (this instanceof ConstructorOne) ? initialise.call(this) : new ConstructorOne();
	}
	ConstructorOne.prototype = new CommonConstructor();

	function ConstructorTwo() {
		return (this instanceof ConstructorTwo) ? initialise.call(this) : new ConstructorTwo();
	}
	ConstructorTwo.prototype = new CommonConstructor();

	function ConstructorThree() {
		return (this instanceof ConstructorThree) ? initialise.call(this) : new ConstructorThree();
	}
	ConstructorThree.prototype = new CommonConstructor();

	return {
		ConstructorOne: ConstructorOne,
		ConstructorTwo: ConstructorTwo,
		ConstructorThree: ConstructorThree
	};

}());

Each of these classes can have distinct methods appended to their prototype without those methods being appended to the other classes, and they all inherit from “CommonConstructor”, but further modularisation might better express the single responsibility principle.

I could isolate these constructors with the Module Pattern but I have decided instead to implement the Asynchronous Module Definition API. I can separate module definitions into individual files or I can include them within one file but, most importantly, I can describe each module’s dependencies.

I immediately lose the reuse of the initialisation method.

define("common-constructor", function () {
	function Constructor() { }
	Constructor.prototype.prepareInstanceValues = function () { };
	return Constructor;
});
define("constructor-one", ["common-constructor"], function (CommonConstructor) {
	function initialise() {
		this.prepareInstanceValues();
	}
	function Constructor() {
		return (this instanceof Constructor) ? initialise.call(this) : new Constructor();
	}
	Constructor.prototype = new CommonConstructor();
	return Constructor;
});
define("constructor-two", ["common-constructor"], function (CommonConstructor) {
	function initialise() {
		this.prepareInstanceValues();
	}
	function Constructor() {
		return (this instanceof Constructor) ? initialise.call(this) : new Constructor();
	}
	Constructor.prototype = new CommonConstructor();
	return Constructor;
});
define("constructor-three", ["common-constructor"], function (CommonConstructor) {
	function initialise() {
		this.prepareInstanceValues();
	}
	function Constructor() {
		return (this instanceof Constructor) ? initialise.call(this) : new Constructor();
	}
	Constructor.prototype = new CommonConstructor();
	return Constructor;
});
define("library", ["constructor-one", "constructor-two", "constructor-three"], function (ConstructorOne, ConstructorTwo, ConstructorThree) {
	return {
		ConstructorOne: ConstructorOne,
		ConstructorTwo: ConstructorTwo,
		ConstructorThree: ConstructorThree
	};
});

I could sacrifice some cohesion to reuse the initialisation method by creating a common utility.

define("common", function () {
	function initialise(instance) {
		if (instance instanceof Constructor) {
			instance.prepareInstanceValues();
		}
	}
	function Constructor() { }
	Constructor.prototype.prepareInstanceValues = function () { };
	return {
		Constructor: Constructor,
		initialise: initialise
	}
});
define("module-constructor", ["common"], function (common) {
	function Constructor() {
		return (this instanceof Constructor) ? common.initialise(this) : new Constructor();
	}
	Constructor.prototype = new common.Constructor();
	return Constructor;
});

I could bundle “Constructor” and “initialise” together, modifying the initialisation method, too. I am being particular about instantiation of the constructors, and I am being particular about how I initialise those constructors. Both “Constructor” and “initialise” are exposed publicly.

I’ve been able to reuse the initialisation method and, superficially, it looks as though this is a good place for it. I can see that those initialisation steps are assigned to the prototype of the class defined in the module. When the initialisation method is invoked execution will proceed through those steps provided the enclosing conditional “if” is true.

Alternatively, I could dispose of the bundle and assign the initialisation method to a property of “CommonConstructor”. Since the method isn’t assigned to the prototype it won’t be inherited:

define("common-constructor", function () {
	function Constructor() { }
	Constructor.prototype.prepareInstanceValues = function () { };
	Constructor.initialise = function (instance) {
		if (instance instanceof Constructor) {
			instance.prepareInstanceValues();
		}
	}
	return Constructor;
});

define("module-constructor", ["common-constructor"], function (CommonConstructor) {
	function Constructor() {
		return (this instanceof Constructor) ? CommonConstructor.initialise(this) : new Constructor();
	}
	Constructor.prototype = new CommonConstructor();
	return Constructor;
});

Assigning the initialisation method to property of the constructor, though, only looks superficially to be a good place for it because the method is never invoked by an instance of the constructor, only by instances of constructors inheriting from this one. The initialisation method isn’t anything to do with this specific class.

The awkwardness of this formulation should be evident from trying to write a test for it, and for the formulation preceding. Whether assigned as a property of the bundle or the constructor I can only test the method in a suite for the “module-constructor” module. While tests in a suite for the “common” or “CommonConstructor” modules would need to instantiate the constructor, the class itself doesn’t ever invoke the “initialise” method. We would be testing for something that never occurs. We can make it occur, but that’s a different matter.

Were it not for the inheriting classes, the “initialise” method wouldn’t exist at all: so it belongs with them, as do tests for it.

I can sacrifice reuse to cohesion and not be too concerned about any unintended consequences elsewhere in the code. I’m not offering a feature I don’t need to, I’m not expecting developers to work with my code in an unusual way, nor do I need to defend too much against the use of a feature in a way that I didn’t intend. Increased modularity does enable other developers to use all of my classes outside of the “library” structure, but that’s fine because the module declares its own dependencies. I have no responsibility for any implementation beyond ensuring that the code is distributed correctly.

Solutions to problems posed by reusing initialisation with other Constructors

It’s possible for other developers to inherit from your constructors, but their descendant constructors won’t immediately have access to your “initialise” method. You may want to offer an inheritance mechanism as a feature with your initialisation enabled internally, by default.

define("common-constructor", function () {
	return function Constructor() { }
});
define("module-constructor", ["common-constructor"], function (CommonConstructor) {

	function initialise() { /* initialisation */ }
	function descendant(Ancestor) {
		function Constructor() {
			initialise.call(this);
		}
		Constructor.prototype = new Ancestor();
		Constructor.prototype.descendant = (function (Ancestor) {
			return function () {
				return descendant.call(this, Ancestor);
			}
		}(Constructor));
		return Constructor;
	}

	function Constructor() {
		initialise.call(this);
	}
	Constructor.prototype = new CommonConstructor();
	Constructor.prototype.descendant = (function (Ancestor) {
		return function () {
			return descendant.call(this, Ancestor);
		}
	}(Constructor));
	return Constructor;

});

The “module-constructor” module declares both a private “initialise” function and a private “descendant” function. It also declares a public “Constructor” function which inherits from “common-constructor” and is returned from the module to whatever consumes it.

“Constructor” has a method assigned to its prototype named “descendant” which uses the Module Pattern to isolate the “Constructor” function as a variable named “Ancestor” within scope of the closure function it returns. When invoked, the closure function itself calls the private “descendant” function, passing “Ancestor” as an argument.

At this point, the private “descendant” function establishes an internal recursion: it creates another “Constructor” function which inherits from “Ancestor”, assigning another “descendant” method to its prototype which uses the Module Pattern to isolate the “Constructor” function as a variable named “Ancestor” within scope of the closure function it returns. And when invoked, that closure function calls the private “descendant” function …

Because every constructor created with this mechanism is created within the same context as the private “initialise” function, they can now all invoke it. In fact, in this formulation, they shall always invoke it.

A first elaboration:

function descendant(Ancestor) {
	function Constructor() {
		initialise.call(this);
	}
	Constructor.prototype = new Ancestor();
	Constructor.prototype.descendant = (function (Ancestor) {
		return function () {
			return descendant.call(this, Ancestor);
		}
	}(Constructor));
	Constructor.prototype.ancestor = (function (ancestor) {
		return function () {
			return ancestor;
		}
	}(this));
	return Constructor;
}

A method assigned to its prototype named “ancestor” which uses the Module Pattern to isolate the context “this” as a variable named “ancestor” within scope of the closure function it returns. When invoked, the closure function returns “ancestor” to the caller. Which is to say, a child instance can return its parent instance.

A second elaboration:

function descendant(Ancestor) {
	function Constructor() {
		Ancestor.call(this);
	}
	Constructor.prototype = new Ancestor();
	Constructor.prototype.descendant = (function (Ancestor) {
		return function () {
			return descendant.call(this, Ancestor);
		}
	}(Constructor));
	return Constructor;
}

When instantiated, the “Constructor” constructor function invokes the “Ancestor” constructor function in the context of “this”, which is the instance. Consequently, that “Ancestor” constructor function invokes its own “Ancestor” constructor function, and so on, until the “module-constructor” module “Constructor” function is reached, which invokes “initialise”. That chain of calls may be useful; it may not.

Whether you want to offer an inheritance mechanism with your initialisation enabled by default, or not, developers using your library can still access the private “initialise” method by calling your constructor from within their own.

define("common-constructor", function () {
	return function Constructor() { }
});
define("module-constructor", ["common-constructor"], function (CommonConstructor) {

	function initialise() { /* initialisation */ }

	function Constructor() {
		initialise.call(this);
	}
	Constructor.prototype = new CommonConstructor();
	return Constructor;

});
require(["module-constructor"], function (ModuleConstructor) {

	function Constructor() {
		ModuleConstructor.call(this);
	}
	Constructor.prototype = new ModuleConstructor();

	var instance = new Constructor();
	/*
		...
	*/

});

And now it should be possible to see how a private “initialise” function can be reused or overridden by every inheriting class:

define("common-constructor", function () {
	function initialise() { /* initialisation */ }
	return function Constructor() {
		initialise.call(this);
	}
});
define("module-constructor", ["common-constructor"], function (CommonConstructor) {

	function initialise() { /* initialisation */ }

	function Constructor() {
		CommonConstructor.call(this);
		initialise.call(this);
	}
	Constructor.prototype = new CommonConstructor();
	return Constructor;

});
require(["module-constructor"], function (ModuleConstructor) {

	function initialise() { /* initialisation */ }

	function Constructor() {
		ModuleConstructor.call(this);
		initialise.call(this);
	}
	Constructor.prototype = new ModuleConstructor();

	var instance = new Constructor();
	/*
		...
	*/

});

Advertisements

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".

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.