Monday, March 15th, 2010

A deep dive and analysis of the JavaScript Module pattern

Category: JavaScript

<>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
< view plain text >
  1. var MODULE_TWO = (function (old) {
  2.     var my = {},
  3.         key;
  4.      
  5.     for (key in old) {
  6.         if (old.hasOwnProperty(key)) {
  7.             my[key] = old[key];
  8.         }
  9.     }
  10.      
  11.     var super_moduleMethod = old.moduleMethod;
  12.     my.moduleMethod = function () {
  13.         // override method on the clone, access to super through super_moduleMethod
  14.     };
  15.      
  16.     return my;
  17. }(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
< view plain text >
  1. var MODULE = (function (my) {
  2.     var _private = my._private = my._private || {},
  3.         _seal = my._seal = my._seal || function () {
  4.             delete my._private;
  5.             delete my._seal;
  6.             delete my._unseal;
  7.         },
  8.         _unseal = my._unseal = my._unseal || function () {
  9.             my._private = _private;
  10.             my._seal = _seal;
  11.             my._unseal = _unseal;
  12.         };
  13.      
  14.     // permanent access to _private, _seal, and _unseal
  15.      
  16.     return my;
  17. }(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
< view plain text >
  1. MODULE.sub = (function ()) {
  2.     var my = {};
  3.     // ...
  4.      
  5.     return my;
  6. }());

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!

Related Content:

Posted by Dion Almaer at 6:38 am
8 Comments

+++--
3.5 rating from 18 votes

8 Comments »

Comments feed TrackBack URI

This looks really useful – I’ll have to spend some time reading the original article when I get the chance.

Comment by Skilldrick — March 15, 2010

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 (){})();” ?

Comment by hackwaly — March 15, 2010

From the article:

The module pattern is good for performance.

Er. No it’s not. I’ll stick to the prototype pattern for performance.

Comment by deanedwards — March 15, 2010

Yes, the prototype pattern for classes which may be instantiated. But for singletons this is slimmest:

Module.sub = new function(){// add properties to “this”};

Calls the function as a constructor then discards it. The constructed object is referenced by Module.sub And you can use “this” within it.

Comment by ExtAnimal — March 15, 2010

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

Comment by elmuchacho — March 15, 2010

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!

Comment by bcherry — March 15, 2010

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.

Comment by AngusC — March 15, 2010

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.

Comment by steida — March 15, 2010

Leave a comment

You must be logged in to post a comment.