The “module” pattern has become widespread due to the opportunity it provides to structure and organize application code as it`s size increases.
Unlike other languages, JavaScript lacks a special syntax for creating packages, but the module pattern provides everything you need to create independent pieces of code that can be considered “black boxes” which can be added, replaced or removed in accordance with the needs of your application.
The first step is to create a namespace. Let`s create a helper module containing methods for working with arrays:
var SOFTXPATH = SOFTXPATH || {};
SOFTXPATH.createNameSpace = function(ns_string) {
var modules = ns_string.split(‘.’),
root = SOFTXPATH,i;
// discard the initial prefix - the name of the global object
if (modules[0] === “SOFTXPATH”) {
modules = modules.slice(1);
}
for (i = 0; i < modules.length; i + = 1) {
// create a property if it is missing
if (typeof root[modules[i]] === “undefined”) {
root[modules[i]] = {};
}
root = root[modules[i]];
}
return root;
};
SOFTXPATH.createNameSpace(‘utilities.array’);
The next step is to define the module. At this stage, an immediately-invoked function is used, which creates a private scope (if needed). This function returns an object - the module itself with a public interface that can be used by application which imports the module:
SOFTXPATH.utilities.array = (function () {
return {
// will be implemented later...
};
}());
Then we need to add the public methods:
SOFTXPATH.utilities.array = (function() {
return {
inArray: function(needle, haystack) {
// ...
},
isArray: function(a) {
// ...
}
};
}());
In the private scope created by the immediately-invoked function, you can declare private properties and methods, if necessary.
At the very beginning of the immediately-invoked function we need to place all the dependency declarations needed for the module. Following the variable declarations, you can put the module initialization code, which will be executed only once.
The final result is an object returned by the immediately-invoked function containing the public members of the module:
SOFTXPATH.createNameSpace(SOFTXPATH.utilities.array’);
SOFTXPATH.utilities.array = (function() {
// dependencies
var utilitiesObj = SOFTXPATH.utilities.object,
utilitiesLang = SOFTXPATH.utilities.lang,
// private properties
array_string = “[object Array]”,
objps = Object.prototype.toString;
// private methods
// ...
// end of var statement
// implement an optional initialization code
// ...
// public members
return {
inArray: function(seek, arr) {
for (var i = 0, max = arr.length; i < max; i + = 1) {
if (arr[i] === seek) {
return true;
}
}
},
isArray: function(a) {
return objps.call(a) === array_string;
}
// ... other methods and properties
};
}());
The “module” pattern is widely used in practice and is the recommended way to organize application code, especially as its volume increases.