JavaScript namespaces without ASP.NET AJAX
In ASP.NET AJAX, you create a namespace by calling
Type.registerNamespace('My.Namespace.Of.Choice');
The necessary object dictionaries are built, names resolved, everything is groovy. But what if you can’t use that for what ever reason…
I’m working in a project that can’t use the ASP.NET AJAX Client Libraries for reasons that are irrelevant. I want to create a namespace, so my objects don’t collide with others. The answer turned out to be uber-simple:
var MyNamespace = MyNamespace ? MyNamespace : {};
( idea spurred from an irrelevant post at http://www.lixo.org/archives/2007/09/14/javascript-put-everything-in-a-namespace/ )
Now, I need to do that for each level:
var My = My ? My : {};
var My.Namespace = My.Namespace ? My.Namespace : {};
var My.Namespace.Of = My.Namespace.Of ? My.Namespace.Of : {};
var My.Namespace.Of.Choice = My.Namespace.Of.Choice ? My.Namespace.Of.Choice : {};
After all, a JavaScript “namespace” is just an object, and an object is just a dictionary, and a dictionary just has keys and values. In effect a JavaScript “namespace” is just a tree of nested object instances that eventually contain my real object. (see http://odetocode.com/Articles/473.aspx and https://robrich.org/archive/2007/09/16/Object-Oriented-JavaScript.aspx – yes, I need to blog that better)
Ok, if I want it to be compatible with ASP.NET AJAX Client Libraries, my definition needs to expand to this:
var My = My ? My : function() {
this.__namespace = true;
this.__typeName = “My”;
}
var My.Namespace = My.Namespace ? My.Namespace : function() {
this.__namespace = true;
this.__typeName = “My.Namespace”;
};
( see C:\Program Files\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\MicrosoftAjaxLibrary\System.Web.Extensions\1.0.61025.0\MicrosoftAjax.debug.js
where it defines Type.registerNamespace around line 850 )
or using the prototype model more fully (technically, it’s just a single instance of this var, so this is way overkill):
var My = My ? My : function() {}
My.prototype.__namespace = My.prototype.__namespace ? My.prototype.__namespace : true;
My.prototype.__typeName = My.prototype.__typeName ? My.prototype.__typeName : "My";
My.Namespace = My.Namespace ? My.Namespace : function() {}
My.Namespace.prototype.__namespace = My.Namespace.prototype.__namespace ? My.Namespace.prototype.__namespace : true;
My.Namespace.prototype.__typeName = My.Namespace.prototype.__typeName ? My.Namespace.prototype.__typeName : "My.Namespace";
Suddenly I’m very grateful for all the work that went into the ASP.NET AJAX Client Libraries that I don’t need to do…
On a similar but completely different note, if you’re just insuring names don’t collide, a technique of wrapping your whole code block in an anonymous function works nicely ( source: http://ajaxcookbook.org/javascript-api-namespaces/ )
The technique involves putting (function(){
before your code and })();
after it. Your whole block of code is now a function that’s executed once, then goes out of scope. Ok, if you don’t declare your var inside the function, and you happen to name it identically to a neighboring var, I could see collisions, but likely you’re all-but safe.
Rob