Namespace collisions are a serious concern in JavaScript. It is quite trivial to overwrite an object which is being used by another piece of code without being aware of it. Such issues are inherently difficult to debug: the offending (overwriting) code will function perfectly, while the damaged code (which ordinarily works fine) will inexplicably fail.
While JavaScript has no built-in means of defining packages or modules, "namespace objects" may be used to effectively segregate modules from one another. Namespace objects are incredibly simple: just define an object, and add methods, classes, variables, and constants to it. Namespaces can be even be created within namespaces.
The example shows a couple of namespace objects (Utils
and Utils.Array
) which define a couple of methods:
Utils = {}; Utils.randomInteger = function(maximum) { return parseInt(Math.random() * maximum); }; Utils.Array = { }; Utils.Array.indexOf = function(array, item) { for (var i = 0; i < array.length; ++i) { if (array[i] == item) { return i; } } return -1; }
Object literal syntax may also be used when creating namespaces. The following code is equivalent to the previous example:
Utils = { randomInteger: function(maximum) { return parseInt(Math.random() * maximum); }, Array: { indexOf: function(array, item) { for (var i = 0; i < array.length; ++i) { if (array[i] == item) { return i; } } return -1; } } };
You may want to use the above syntax a bit sparingly though as it can become a bit indentation-heavy. One approach that strikes a good balance is to not declare "sub-Namespacse" within the object literal.
Make certain to avoid inadvertently declaring global variables inside of functions by using the var
keyword for all non-global variable declarations. The following code overwrites the global variable "total", effectively destroying itself after its first invocation.
function total(values) { total = 0; for (var i = 0; i < values.length; ++i) { total += values[i]; } return total; };
To correct this problem, we must declare the variable total
in local scope using the var
keyword:
function total(values) { var total = 0; for (var i = 0; i < values.length; ++i) { total += values[i]; } return total; };
And for the record, this example function should also be placed in a namespace, but doing so would not demonstrate the fantastic catastrophe that can occur if you fail to declare a variable in local scope using var
.