Show love to the Module Pattern
Back in February 2006 I declared my love for the object literal explaining that it is a great way of making sure your scripts don’t interfere with others as all you expose to the world is a single object name. Instead of
function init(){}
function doStuff(){}
var myMessage = 'oi, gerrof!';
which might be easily overwritten you can use
myScript = {
init:function(){},
doStuff:function(){},
myMessage:'oi, gerrof!'
}
and this way make sure that they don’t get overwritten or overwrite other methods or variables. You can access them as myScript.init(), myScript.doStuff() and myScript.myMessage. I liked this idea so much I argued for a length of time with my technical editor at that time that I want my book to be based on this kind of scripting or not at all.
The only annoyance I had with this is that it still leads to rather big methods, as you have to use the long name for every call of variables inside the object. True, you can use this, but when you use event handling and you don’t use the scope correction of the YUI event you’ll use that for the element the event occured on.
myScript = {
init:function(){
this.doStuff();
},
doStuff:function(){},
myMessage:'oi, gerrof!'
}
Is therefore not necessarily possible, so you need to use:
myScript = {
init:function(){
myScript.doStuff();
},
doStuff:function(){},
myMessage:'oi, gerrof!'
}
This, in much more complex scripts, can lead to a lot of code and typing (unless you use an IDE) and just seems bloated. I had a lot of problems fitting object literal scripts into 80 character code templates for the book and magazine articles for example.
The solution to shorter code is once again a thing from the mad JavaScript scientist’s lab of Douglas Crockford called the Module Pattern. If you want a very detailed and good explanation of what it does in terms of OO sorcery, check out the easy to follow explanation of the Module Pattern by Eric Miraglia on the YUI blog.
What the Module Pattern does for me on top of that is that it keeps my code short. I only expose those methods as public that need to be and then I can call them inside the main object by name of the method and not by objectname.methodname.
myScript = {
massivelyLongVariableProbablyGerman:1,
thisIsReallyLong:function(n){},
doStuff:function(n){},
init:function(){
myScript.doStuff(myScript.massivelyLongVariableProbablyGerman);
myScript.thisIsReallyLong(myScript.massivelyLongVariableProbablyGerman);
}
}
myScript.init();
becomes
myScript = function(){
var massivelyLongVariableProbablyGerman = 1;
function thisIsReallyLong(n){};
function doStuff(n){};
return {
init:function(){
doStuff(massivelyLongVariableProbablyGerman);
thisIsReallyLong(massivelyLongVariableProbablyGerman);
}
};
}();
myScript.init();
However, there are two problems remaining: if you want to call one public method from another public method you’d still need to go either via the this route or by prepending the main object name:
myScript = function(){
var massivelyLongVariableProbablyGerman = 1;
function thisIsReallyLong(n){};
function doStuff(n){};
return {
init:function(){
doStuff(massivelyLongVariableProbablyGerman);
thisIsReallyLong(massivelyLongVariableProbablyGerman);
otherPublic() // < - has MASSIVE FAIL!
this.otherPublic() // <- works
myScript.otherPublic() // <- works
},
otherPublic:function(){
}
};
}();
myScript.init();</>
The other problem is that I am not too happy about the return {} with all the public methods in it, it still looks a bit alien to me. Caridy Patiño offered a solution to that problem on the YUIblog by simply creating an object with a short name inside the main object that can act as a shortcut for public methods to call each other:
var myScript = function(){
var pub = {};
var massivelyLongVariableProbablyGerman = 1;
function thisIsReallyLong(n){};
function doStuff(n){};
pub.init = function(){
doStuff(massivelyLongVariableProbablyGerman);
thisIsReallyLong(massivelyLongVariableProbablyGerman);
pub.otherPublic();
};
pub.otherPublic = function(){
};
return pub;
}();
myScript.init();
This also saves me one level of indentation which means I can fit even more code in 80 characters. I will use that much more in earnest now.

July 24th, 2007 at 5:08 pm
July 25th, 2007 at 2:09 am
August 4th, 2007 at 8:25 pm
posted by admin at 2:19 pm [...]
September 24th, 2007 at 11:22 am
July 24th, 2007 at 6:42 pm
I really love these patterns, but I’m always a little nervous using them because I know that someone else will end up having to modify or maintain the code I produce.
July 24th, 2007 at 8:04 pm
Thanks to Chris for this excellent explanation,
I’ll add another benefit of this pattern, and is the possibility of use the reference to the public object inside the public methods when a method is called with other scope:
if you call onChange method using another scope, for ex:
In this case, the execution scope for the onChange method will be {foo: 2, anotherFoo: 3}, which means that you will not be able to call another public Var or Method, but the method will keep the closure, allowing you to use the pub’s reference, and the private Methods and Vars.
September 12th, 2007 at 4:26 pm
I’m not sure why this pattern keeps including an init() method that gets called explicitly after the fact. Of course, if you need to delay initialization of your module this makes sense.
If, however, you plan on calling your init() method right away, save yourself some overhead and place your initialization code inside the body of your module function. That anonymous function is already initializing your module (by defining it as a function that you call immediately whose job is to create and return your module), so set up your initial state there.
September 12th, 2007 at 4:34 pm
i don’t know why people keep including an explicit init() method with this pattern. Of course that makes sense if you need to delay initialization until some event or other condition is met.
However, since the purpose of the anonymous function at the heart of this pattern is create and return your module, why not save yourself some overhead, inline your initialization code into that anonymous function, and setup initial state as part of creating your module?
eg.
var myscript = function() { // declare private variables // declare private functions // *** set up initial state *** return { // declare public variables & functions } }();January 2nd, 2008 at 7:19 am
[...] Wait till I come! » Blog Archive » Show love to the Module Pattern (tags: javascript patterns dom tutorial) [...]
February 20th, 2008 at 5:44 pm
[...] on trouve pas mal d’articles sur le net qui traitent du même sujet, comme celui-ci, ou encore celui-là . Classé sous javascript , Laisser un [...]
March 28th, 2008 at 6:15 am
I like these patters. Nice post!
January 22nd, 2009 at 2:15 am
[...] le guste o prefiera la sintaxis tradicional, siempre se puede recurrir al método que proponen en wait-till-i.com, que consiste en la creación de un objeto vacÃo dentro del objeto principal, al que se le van [...]
February 11th, 2009 at 4:38 am
[...] I found and article that explains exactly that. It explains the Module Pattern and how to use it to limit the scope of [...]