Module Pattern vs. Custom Objects

A little while ago I tried to gather together information about what kind of programming patterns are out there in the wild when it comes to JavaScript and describing the characteristics of each of those. At Yahoo!, the two patterns we use almost exclusively are Module Pattern (for functionality to be implemented on various properties) and Custom Objects (as in the YUI library, for example). The question I was asking myself is how they behave differently and whether you could do the same thing with both of them.

For this article I am sticking to the same simple example that I already used in my previous article. But to make it a little bit more interesting, we have two lists of links, not just one:

<ul id="list-1"> <li><a href="http://news.bbc.co.uk/">News on BBC website</a></li> <li><a href="http://nytimes.com/">Frontpage of The New York Times</a></li> <li><a href="http://www.guardian.co.uk/">Guardian Unlimited</a></li> </ul> <ul id="list-2"> <li><a href="http://valleywag.com/">Valleywag</a></li> <li><a href="http://techcrunch.com/">TechCrunch</a></li> <li><a href="http://www.yahoo.com/">Yahoo!</a></li> </ul>

Clicking on one of the links should simply switch the background color to a value we would like to provide as a parameter. Essentially, we want to have two separate objects in the end that act independently from each other.

Custom Objects

The structure of the source code roughly remains the same as the one used in my previous article. The only difference is that I set up the constructor function in a way that it is possible to pass values to it (colors, Id of the list and some random value which we will use later to prove that we have two distinct objects).

function anchorChangerProto (colors, list, random) { this.config = { colors: colors, list: list } this.test = random; }

No rocket science, pretty straight forward. I am also creating a logRandom() function which will log the value of test to the console.

anchorChangerProto.prototype.logRandom = function () { console.log(this.test); }

Nothing unexpected in here either. So the full source code for anchorChangerProto looks like this:

function anchorChangerProto (colors, list, random) { this.config = { colors: colors, list: list } this.test = random; } anchorChangerProto.prototype.changeColor = function (linkObj, newColor) { linkObj.style.backgroundColor = newColor; }; anchorChangerProto.prototype.init = function () { var self = this; // get all links from particular list var anchors = this.config.list.getElementsByTagName("a"); var size = anchors.length; for (var i = 0; i < size; i++) { anchors[i].color = self.config.colors[i]; anchors[i].onclick = function () { self.changeColor(this, this.color); return false; }; } }; anchorChangerProto.prototype.logRandom = function () { console.log(this.test); }

At the end of the page, in a <script> block I can now instantiate my objects and call their init methods.

var changer1 = new anchorChangerProto([ "#F63", "#CC0", "#CFF" ], document.getElementById("list-1"), "first changer"); changer1.init(); var changer2 = new anchorChangerProto([ "#009", "#990", "#909" ], document.getElementById("list-2"), "second changer"); changer2.init();

The new operator creates a generic object, sets its __proto__ value to anchorChangerProto.prototype, and passes that object to the constructor function as the this keyword. I tried to explain that in my other article about inheritance in JavaScript.

After these statements, we can call the logRandom function for each object to prove that we have indeed created two distinct objects which act independently from each other. Have a look at the demo page for this example.

changer1.logRandom(); // logs: "first changer" changer2.logRandom(); // logs: "second changer"

Everything as expected. Now the question is whether the same thing can be achieved with the Module Pattern.

Module Pattern

Page 1 of 3 | Next page