Creating JavaScript Namespaces

24. September 2010 15:01

When using JavaScript these days, it is generally a good idea to namespace your javascript methods so that they don't polute the global namespace.

if (typeof mysite == 'undefined') var mysite = {};
mysite.section = mysite.section || {};
mysite.section.subNamespace = mysite.section.subNamespace || {};
mysite.section.subNamespace.component = (function(){ ... }());

This allows you to create a clean separation of your utilization. Although you may not want to go as deep as the example above, you can see how this could very well become cumbersome when you want to declare one or more namespaces. It would be nice to have a helper method that lets you simply declare namespaces.

//declare a single namespace
namespace('mysite.section.subNamespace.component');

//declare multiple namespaces at once
namespace('mysite.section2', 'mysite._utilities');

This works out much nicer, and is easier to repeate as-needed when creating your namespaces. The function I am using for this is below.

var namespace = (function(root){
	//regular expression to limit formatting of namespaces
	var nsre = /^([\$\_a-z][\$\_a-z\d]*\.?)+$/i

	//define returned function
	return function(ns) {
		var args = Array.prototype.slice.call(arguments);
		var ret = [];
		while (args.length) {
			ns = genNS(args.shift());
			if (ns) ret.push(ns);
		}
		if (ret.length == 0) return; //undefined, no valid input
		if (arguments.length == 1) return ret[0]; //only a single input, return that namespace
		return ret; //used overload for multiple namespaces, return the array/list
	}
	
	//private static method to generate a single namespace
	function genNS(ns) {
		if (!ns.match(nsre)) return;
		ns = ns.split('.');
		var base = root;
		for (var i=0; i<ns.length; i++) {
			base[ns[i]] = base[ns[i]] || {};
			base = base[ns[i]];
		}
		return base; //return resulting namespace object
	}
}(this));

This functionality is very useful, and is included in a number of API toolkits. You could replace the var namespace declaration and attach it to an existing object such as $.ns, which would attach it to an existing reference.

If you have suggestions for future topics, feel free to leave a comment or contact me via email.

Comments

9/26/2010 2:10:06 AM #

M A Hossain Tonu

Good Smile
If you interested on some "JavaScript Object Literal Namespacing"
can check out this one too http://wp.me/pgwfF-1D

M A Hossain Tonu United States |

9/27/2010 2:14:55 AM #

Kai

And this is the opposite, which comes in handy too.

Sometimes you need to know, if a (deeper structured) part of a namespace is actually declared. Use this to get a pointer to it or null, if it's undeclared:


            // checks the DOM tree and returns the existing object, if found
            function getNamespaceObject(nsString) {
                var objPointer, nsElement, i;
                nsElement = nsString.split (".");
                objPointer = window;
                for (i=0; i<nsElement.length; i++) {
                    if ((typeof (objPointer[nsElement[i]]) === "object")
                    || (typeof (objPointer[nsElement[i]]) === "function")) {
                        objPointer = objPointer[nsElement[i]];
                    } else {
                        objPointer = null;
                        break;
                    }
                }
                return objPointer;
            }

Kai Germany |

Comments are closed

Tracker1

Michael J. Ryan aka Tracker1

My name is Michael J. Ryan and I've been developing web based applications since the mid 90's.

I am an advanced Web UX developer with a near expert knowledge of JavaScript.