JavaScript Namespacing

Posted by Jack Hsu Wed, 24 Mar 2010 14:48:00 GMT

One of the first things you learn programming in JavaScript is, "Global variables are evil." This is especially true when writing a JavaScript library, but I’d take that advise even otherwise to avoid unnecessary headaches.

As an avid jQuery user, one thing I do in almost every project is define a namespace function on the jQuery object.

jQuery.namespace = function(ns, obj) {
    var ns = ns.split('.'), 
        p = window,
        i;
    for(i=0; i<ns.length; i++) 
        p = p[ns[i]] = p[ns[i]] || {};
    if (obj) 
        jQuery.extend(p, jQuery.isFunction(obj) ? obj(p) : obj);
};
 

This function will take in either an object or a function that takes in an object, then create the namespace or extend it if it exists.

// Example 1
$.namespace('foo.bar', {
    myVar: 1, myOtherVar: 2, someFunction: function() { alert(this.myVar + ',' + this.myOtherVar); }
});
foo.bar.someFunction();
//--> alerts "1,2"

// Example 2
$.namespace('faz', { baz: { a: 1, b: 2 } });
$.namespace('faz.baz', function(old /* previous namespace */) {
    old.a = 'new value'; // change previous assignment of a
    old.printMe = function() { alert(old.a + ',' + old.b); };
});
faz.baz.printMe();
//--> alerts "new value,2"

The second example shows a case where an function is passed instead of an object. This is useful for many reasons which I won’t get into… actually you can read a great post here about JavaScript module patterns.

And when jQuery isn’t being used on a project, the following does the exact same.

function namespace(ns, obj) {
    var ns = ns.split('.'), 
        p = window,
        i, k;
    for(i=0; i<ns.length; i++) 
        p = p[ns[i]] = p[ns[i]] || {};
    if (obj) {
        obj = obj instanceof Function ? obj(p) : obj;
        for (k in obj) {
            if (obj.hasOwnProperty(k))
                p[k] = obj[k];
        }
    }
}
 
Bookmark and Share

Leave a comment

(leave url/email »)

   Comment Markup Help Preview comment