james mckay dot net

Blah blah scribble scribble waffle waffle
06
Aug

Namespaces in JavaScript

Namespaces are a common technique used in many programming languages to avoid naming collisions between different parts of your code. Unfortunately JavaScript doesn’t have built in namespace support, but it can be implemented fairly simply by creating a nested hierarchy of objects in the global namespace. A bit like this:

var My = My || {};
My.Cool = My.Cool || {};
My.Cool.Namespace = My.Cool.Namespace || {};

My.Cool.Namespace.showMessage = function(msg) {
    $('#messageBox').html(msg).show();
};

The problem with this is that it’s pretty verbose. It would be far better if you could have a function to declare a namespace and simplify things.

There are several different approaches to this knocking around. Usually, they look something like this:

var ns = namespace("My.Cool.Namespace");
ns.showMessage = function(msg) {
    $('#messageBox').html(msg).show();
};

My approach is a little bit different. Your namespace function takes a second argument, a function which is called to initialise your namespace. You can do this by assigning properties to the this object in the function body:

namespace("My.Namespace", function() {
    "use strict";

    this.showMessage = function(msg) {
        $('#message').html(msg).show();
    };
});

My.Namespace.showMessage('Hello world');

The advantage of this approach is that it implements the JavaScript module pattern, enclosing the entire contents of your file in a single function. Another thing I’ve implemented is the ability to create shortcuts to other namespaces. You can do this by passing them in an additional array to the namespace() function, which then forwards them on to the initialiser:

namespace("My.Namespace", [jQuery, Backbone], function($, bb) {
    "use strict";

    // bb is a shortcut for the Backbone namespace of
    // backbone.js; this example creates a Backbone model
    // called My.Namespace.Note

    this.Note = bb.Model.extend({
        initialize: function() { ... },

        author: function() { ... },

        coordinates: function() { ... },

        allowedToEdit: function(account) {
            return true;
        }
    });
});

I’ve put my namespace function on GitHub, along with some more detailed instructions on how to use it.