JavaScript Namespace Strategy for Large Applications

According to the HTTP Archive, the average site serves 14 JavaScript files. With more reliance on 3rd party code, it is increasingly more important to protect the code from being interfered with by other code used on the same site or application.

Namespacing is the common sense way to do this and a practice that I employ on all my projects, both work and personal. This article demonstrates my approach to structuring namespaces in JavaScript for larger applications.

What is a Namespace?

A namespace is a wrapper for a group of related features or modules which is used to provide an intuitive structure to a larger-scale architecture. Think of how someone shops on Amazon. There is a sporting goods department, books, apparel, etc. All of these are categories of items that are classified in some way.

The best way to illustrate how this works in a programming scenario is to take a look at JavaScript libraries and frameworks. All JS libraries use namespaces, but take slightly different approaches.

BBC’s Glow

The Glow framework uses an IIFE to check to see if there is a Glow namespace in the global object (window if the code is running in the browser), and if it has not been defined before, it is created.

// From Glow 2.0 Alpha
(function() {
    // there can be only one
    if (window.Glow) { return; }
    window.Glow = true;

    window.Glow = function(version, opts) {
        // configures Glow namespace in the window object
    }

    // rest of the library goes here...
})();

jQuery

jQuery sets up a local copy of the jQuery variable and returns the local copy to the global scope:

// From jQuery 1.7
var jQuery = (function() {

    // Define a local copy of jQuery
    var jQuery = function( selector, context ) {
        // The jQuery object is actually just the init constructor 'enhanced'
        return new jQuery.fn.init( selector, context, rootjQuery );
    },

    // Map over jQuery in case of overwrite
    _jQuery = window.jQuery,
    // more configuration code...
    return jQuery;
})();

YUI

YUI considers namespacing to be so important, they included a helper function in their library to allow developers to easily create their own namespaces.

// From YUI 3. The Y namespace is implied for brevity
namespace: function() {
    var a = arguments, o, i = 0, j, d, arg;

    for (; i < a.length; i++) {
        o = this; //Reset base object per argument or it will get reused from the last
        arg = a[i];
        if (arg.indexOf(PERIOD) > -1) { //Skip this if no "." is present
            d = arg.split(PERIOD);
            for (j = (d[0] == 'YAHOO') ? 1 : 0; j < d.length; j++) {
                o[d[j]] = o[d[j]] || {};
                o = o[d[j]];
            }
        } else {
            o[arg] = o[arg] || {};
            o = o[arg]; //Reset base object to the new object so it's returned
        }
    }
    return o;
}

Structuring a Larger Application

Depending on the size of an application, having a complex architecture might be overkill, but basic provisions for a namespace are helpful to identify code, especially when revisiting the site a few months later for maintenance. A basic namespace can be created by:

var MYNS = window.MYNS || {};

Typically, the larger the application, the more important it is to keep code organized. I have found that grouping related features together is the best way to structure a large application.

For example, MooTools has an Element class that provides many helper features for element manipulation and traversal. Child objects like Element.Style are used to extend the parent object. Animation is controlled by the FX class which has subclasses to extend the core features as well. This same modular approach can be applied to application development for related components such as user-interface elements.

// Create the MYNS.UI object to act as a container for
// all user interface features
MYNS.UI = MYNS.UI || {};

MYNS.UI.tabs = function (){
    // methods, variables, and other code goes here
};

MYNS.UI.modal = function (){
    // methods, variables, and other code goes here
};

MYNS.UI.tooltip = function (){
    // methods, variables, and other code goes here
};

Then the same principle can be applied for data models elsewhere in the application:

MYNS.models = MYNS.models || {};

MYNS.models.pages = function(){
    // methods, variables, and other code goes here
};

MYNS.models.authors = function(){
    // methods, variables, and other code goes here
};

As a general rule, I try to avoid going more than 3 levels deep to avoid excessive look-ups up the prototype/scope chain. This limits any performance detriment if there is a function or variable higher up the scope chain that the application needs to access.

Additional Benefits of Namespacing

Namespacing the code this way can also help take the guess work out of file naming and directory structure. For example, we could use this same convention and put all of our UI components in a file called ui.js and all our models in a file called models.js. We could then use a build tool to combine the files into one larger file at build time before deploying to a production server.

Conclusion

As the amount of third-party JavaScript used in web pages increases, developers need to pay added attention to protecting their code from outside interference. Using a namespace is a simple way to help guard against variables being overwritten and provides added benefits of helping with code organization.

See more articles like this in: javascript architecture development namespace