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.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s