Monday, March 15th, 2010
A deep dive and analysis of the JavaScript Module pattern
<>p>Ben Cherry has a really nice detailed analysis of the module pattern.He starts with the simple pattern that Crock-y documented back in the day..... and then goes on to discuss augmentation (loose and strict) and then deeper into some cool patterns:
Cloning and Inheritance
JAVASCRIPT:
var MODULE_TWO = (function (old) { var my = {}, key; for (key in old) { if (old.hasOwnProperty(key)) { my[key] = old[key]; } } var super_moduleMethod = old.moduleMethod; my.moduleMethod = function () { // override method on the clone, access to super through super_moduleMethod }; return my; }(MODULE));This pattern is perhaps the least flexible option. It does allow some neat compositions, but that comes at the expense of flexibility. As I've written it, properties which are objects or functions will not be duplicated, they will exist as one object with two references. Changing one will change the other. This could be fixed for objects with a recursive cloning process, but probably cannot be fixed for functions, except perhaps with eval. Nevertheless, I've included it for completeness.
Cross-File Private State
One severe limitation of splitting a module across multiple files is that each file maintains its own private state, and does not get access to the private state of the other files. This can be fixed. Here is an example of a loosely augmented module that will maintain private state across all augmentations:
JAVASCRIPT:
var MODULE = (function (my) { var _private = my._private = my._private || {}, _seal = my._seal = my._seal || function () { delete my._private; delete my._seal; delete my._unseal; }, _unseal = my._unseal = my._unseal || function () { my._private = _private; my._seal = _seal; my._unseal = _unseal; }; // permanent access to _private, _seal, and _unseal return my; }(MODULE || {}));Any file can set properties on their local variable _private, and it will be immediately available to the others. Once this module has loaded completely, the application should call MODULE._seal(), which will prevent external access to the internal _private. If this module were to be augmented again, further in the application's lifetime, one of the internal methods, in any file, can call _unseal() before loading the new file, and call _seal() again after it has been executed.
This pattern occurred to me today while I was at work, I have not seen this elsewhere. I think this is a very useful pattern, and would have been worth writing about all on its own.
Sub-modules
Our final advanced pattern is actually the simplest. There are many good cases for creating sub-modules. It is just like creating regular modules:
JAVASCRIPT:
MODULE.sub = (function ()) { var my = {}; // ... return my; }());While this may have been obvious, I thought it worth including. Sub-modules have all the advanced capabilities of normal modules, including augmentation and private state.
Nice work Ben!








This looks really useful – I’ll have to spend some time reading the original article when I get the chance.
MODULE.sub = (function ()) {
var my = {};
// …
return my;
}());
it seems that there’s a syntax error.
why do’t you use “var a = function (){}();” instead of “var a = (function (){})();” ?
From the article:
Er. No it’s not. I’ll stick to the prototype pattern for performance.
Yes, the prototype pattern for classes which may be instantiated. But for singletons this is slimmest:
Calls the function as a constructor then discards it. The constructed object is referenced by Module.sub And you can use “this” within it.
I disagree, the module pattern is pure evil.
1) It deliver poor performance in comparison to the prototype pattern.
2) you end up with spaghetti code that become harder to read
3) Guys do you remember how to declare a simple function?
var myFunc = function(){}
This is a variable that has an anonymous function assigned to it
function myFunc(){}
is a function.
To everyone that think this is the same please read the article below and your view of the Module pattern will change for ever.
http://www.jibbering.com/faq/faq_notes/closures.html
Laurent
Skilldrick – Yeah, there’s a typo. An extra paren before the curly brace. I’ll be fixing that, thanks for finding it! By the way, we use parens around the entire invocation to make it clear when scanning the code that we are not assigning a function to the variable, but the return value of invoking that function. It’s not strictly necessary, but it makes the code clearer, which is a good thing.
hackwaly/deanedwards/ExtAnimal – This is not an alternative to prototypes. This is for static code organization and “singletons”. The alternative to module patterns like this is either a single global namespace, or a single object literal with no private state. The module pattern is completely compatible with prototypal inheritance for member objects.
Dion – The link to my name points at the root of twitter.com, which is surely incorrect :) Thanks for posting this!
I used this pattern about two years ago – without realizing it had a name – in order to retroactively modularize a large chunk of global code. But if I were starting from scratch I’d still use prototype (small p) for multi instance objects because of performance and ease of inheritance/mixins – or plain object literals for single instance objects.
Module pattern is useless JavaScript mannerism junk. It’s simple product of misunderstanding of JavaScript. Hiding properties and methods in anonymous function does not make sense, except two reasons:
1) I need another variable, and no scope pollution. It’s useful for jQuery- (function($) {})(jQuery), for instance.
2) micro optimization, rarely useful, and only just because Internet Explorer.
Anybody who thinks “private in JavaScript is nice” suffer from false illusion of “safe code”. There is no such thing in dynamic language which JavaScript really is.
If you want method or property as “private”, just mark it in documentation, or use underscore prefix (google closure uses it even as suffix). It’s enough to tell our code readers: “Do not call or use this, and do not except that this “private” property will work forever.