Skip to content

Instantly share code, notes, and snippets.

@mckamey
Created January 13, 2012 01:29
Show Gist options
  • Save mckamey/1604154 to your computer and use it in GitHub Desktop.
Save mckamey/1604154 to your computer and use it in GitHub Desktop.
JS Module Pattern A
/*global jQuery */
var App = (function(App, $){
'use strict';
// private members
var foo = 0,
bar = 'bar';
function inc() {
bar = 'baz';
foo++;
}
// export public members
App.foo = {
bar: function() {
return bar+' '+foo;
},
inc: inc
};
// delayed initialization
$(function() {
inc();
});
// ALWAYS return the root module
return App;
})(App || {}, jQuery);
// minified via closure-compiler.appspot.com
var App=function(a,e){function b(){c="baz";d++}var d=0,c="bar";a.foo={bar:function(){return c+" "+d},inc:b};e(function(){b()});return a}(App||{},jQuery);

JS Module Pattern A

Conventions

  • The core of the pattern is the anonymous wrapper function, which is immediately executed leaving no trace.
  • The first argument to the wrapper function is always the application's root namespace logically OR'd with an empty object literal: || {}.
  • The parameter list of the wrapper function includes all externally accessed references (including jQuery, document, window, etc.).
  • The return value of the wrapper function is always the value of the first parameter.
  • The resulting value from the execution of the wrapper function is always assigned to a var declaration for the application's root namespace.

Advantages

  • The anonymous wrapper function provides an isolated space where private members (fields and functions) can exist but aren't able to be read, changed or called from the outside context.
  • The first argument combined with the final assignment of the root namespace ensures that the root namespace has been allocated before it is used but does not trample an existing instance if another module has already allocated it.
  • The parameter list explicitly documents all external references that are accessed by this module.
  • The arguments passed in do not need to be global references but instead could be references to repeatedly used sub-objects, e.g. document.body
  • The parameter list allows obfuscation tools to automatically compact very small var names even for global objects (see the minified version).
  • Other modules within the same root level namespace are able to be defined and included in any order (as long as they do not have inter-dependencies) without trampling each other.
  • The wrapper function provides a closure around the argument values ensuring the references aren't later changed out by another less-defensive script.
  • The enture module is declared and constructed in a single statement.

Disadvantages

  • The return value must always be returned and contain the root namespace object, otherwise the application namespace will be incomplete leading to mysterious errors.
  • Only one root module may be built in the same script (NOTE: this is not really much of an issue as probably avoids an anti-pattern).
  • If var is not used to declare private members, they will actually be created in the global namespace.
  • The conventions must be followed otherwise the benefits of the pattern are not fully realized.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment