Why I don't love JavaScript's Module Pattern

The Module Pattern is the use of closures to create, in essence, private functions that are only accessible by other functions created within that closure. Functions can be attached to an object and returned outside of that function call. This establishes a public API and only the functions defined within that public API will have access to those hidden functions.

The YUI blog documents this well but here is a simple example of the Module Pattern:

var ManageChildren = (function(){ var children = []; return { addChild: function() { /* add to children array */ }, removeChild: function() { /* remove from children array */ } } })();

In this example, the ManageChildren object will have two methods: addChild and removeChild. From outside the wrapper function, you cannot access the children array that is defined within.

After having worked with and used this pattern for some time, I now avoid it.

Debugging

When it comes to troubleshooting a particular troublesome page, I like to crank open Firebug's console and play around willy-nilly. The ability to reshape objects lets me test theories before putting them into practice with real code. It also allows me to inspect things to make sure they're working as they should.

Going back to that example I just showed, what if you needed to determine the length of the children array? It's not exposed. Which means you have to insert logging code, or create a breakpoint. In either case, you're forcing a page refresh to re-execute the code.

Now imagine this code was minified and deployed to a live server. It works locally but stopped working on a live server. How much do you feel like trying to add logging code or breakpoints? (Try adding a breakpoint to minified code in Firebug.)

Avoiding the Module Pattern makes debugging easier.

Make extending easier

Another frustration I have with it is the difficulty in being able to extend that object. You can't just add additional functions onto it because you won't have access to the properties defined within.

Take a look at this attempt to extend our object:

ManageChildren.getLength = function(){ return children.length; }

That won't work. Neither will this.children.length , or anything else you try, because children is a variable that's only available to any function declared within that closure.

Aspect-oriented Programming

One other trick with JavaScript that I sometimes like to take advantage of is similar to aspect-oriented programming. While aspect-oriented programming is a deep subject, the key thing I took away from it was the ability to append code before or after a function call. It feels like an event handler. Here's another fun example:

var oldChild = ManageChildren.addChild; ManageChildren.addChild = function(){ /* do what you need to */ oldChild(); }

See what I did? I took the old function and replaced it with my own. Then I proceeded to call the old function. With the module pattern, though, I wouldn't have access to any of those hidden properties. I could never actually add an element to the children array because it's private.

JavaScript should be malleable

One of the features that attracts me to developing in JavaScript is the ability to manipulate objects so readily. As a result, the module pattern is something I try to avoid.