- The first statement of the script ensures the application's root namespace has been allocated by redeclaring and assigning itself logically OR'ing with an empty object literal:
|| {}
. - The core of the pattern is the anonymous wrapper function, which is immediately executed leaving no trace.
- The parameter list of the wrapper function includes all externally accessed references (including
jQuery
,document
,window
, etc.). - The wrapper function always returns the sub-module being defined.
-
Provides slightly more terse module creation internally in the wrapper function but can still be assigned to a larger nested structure.
-
The root namespace does not need to be passed in if it isn't used internally.
-
The first statement 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 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 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.
-
If the module is a namespace nested deeper than the first level, the initial line may be repeated for other intermediate levels and the immediate parent passed in rather than the root. For example:
var App = App || {};
App.foo = App.foo || {};
App.foo.bar = (function(){ ... return { ... }; })();
- slightly less encapsulated generation of the app namespace.
- The return value must always be returned and contain the module 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.