Zach’s ugly mug (his face)

Zach Leatherman

Namespacing outside of the YAHOO Namespace

28 Aug 2007 Read in about 6 minutes

YAHOO.namespace(). A lovely little utility function subject that I’ve written about before. If you’ve never heard of YAHOO.namespace or aren’t even familiar with namespacing, I’d read that article first.

I’ll be honest, using the YAHOO namespace to store my own code makes my bunghole tighten just a little bit. What if I had written code stored under YAHOO.tool, which was unused prior to YUI 2.3.0? What would I do now? I’d have to rewrite my code, or never include any of the wonderful YAHOO.tool.TestCase, put together by Nicholas Zakas. As is traditional with most of my weblog posts, I try not to just complain about a problem without giving you a solution (but let’s be honest, only if it doesn’t take too much work).

Let’s rewrite the YAHOO.namespace function to work outside of the YAHOO Namespace, so we can do things like this:

namespace( 'zachsWorld.partyTime' );
zachsWorld.partyTime = function() {
alert( 'Excellent.' );
}
zachsWorld.partyTime(); // obviously would alert: Excellent.

Here’s some code:

function namespace() {
var a=arguments, o=null, i, j, d;
for (i=0; i<a.length; i=i+1) {
d=a[i].split(".");
o=window;
for (j=0; j<d.length; j=j+1) {
o[d[j]]=o[d[j]] || {};
o=o[d[j]];
}
}
return o;
};

Obviously this is just a modification of the YAHOO.namespace function. I’d recommend putting this under your own namespace (I’m trying to put most of the code I write on this website under the Y2 namespace, but everyone should have their own parent namespace), like so (any namespaces you create using this function won’t use the parent namespace assigned here by default):

if (typeof Y2 == "undefined") {
var Y2 = {};
}
Y2.namespace = function() { /* copy function contents from above. */ };

But you can do whatever you want. This is one of the functions that I think separates YUI from the other frameworks out there, giving an easy utility to organize your code. This is something I think jQuery seriously lacks, noting from the code inside the many jQuery plugins contributed by end users. Many jQuery contributors do not organize their code, putting multiple unnecessary top level functions into jQuery.fn as methods, or into the jQuery object itself as functions. People whine about polluting the global namespace… I suppose it might be considered nitpickey to whine about the jQuery namespace. Okay you whiney bastard, let’s help out and put this into jQuery!

// include jQuery first.
jQuery.namespace = function() {
var a=arguments, o=null, i, j, d;
for (i=0; i<a.length; i=i+1) {
d=a[i].split(".");
o=window;
for (j=0; j<d.length; j=j+1) {
o[d[j]]=o[d[j]] || {};
o=o[d[j]];
}
}
return o;
};

Please note, this method does NOT work using jQuery methods with an element context, such as jQuery(‘div’).myNamespace.myMethod(). Your element context won’t be carried through to myMethod().

However, you can use it for jQuery functions, such as this:

// definition
jQuery.namespace( 'jQuery.debug' );
jQuery.debug.test1 = function()
{
alert( 'test1 function' );
};
jQuery.debug.test2 = function()
{
alert( 'test2 function' );
};
// usage
jQuery.debug.test1();
jQuery.debug.test2();

For more information, you can read Global Domination, an article written by Douglas Crockford, or Best Practices for Writing jQuery plugins.

Updated: fixed some weird source parsing errors introduced by the code formatting plugin.

8 Comments

➡ Load Disqus to Leave a Comment ⬅

Nicholas C. Zakas

09 Sep 2007 at 11:15PM

I'm glad you're enjoying using YUITest. I think your point about namespacing is well-taken, but the YAHOO.namespace() function is non-destructive. If you were already using YAHOO.tool, then YAHOO.namespace() won't overwrite the existing one so all of your functionality will be safe.

By the way, where's your contact information? I'd like to have an offline conversation sometime. Stop by my site and drop me a line when you have a second.

Are you sure your jQuery namespace function works? I get the following error in Firefox3, Safari etc.:

Error: invalid flag after regular expression
Source File: http://localhost/~matias/canalwebtv2008/client/js/base.js
Line: 7, Column: 16
Source Code:
for (i=0; i<a .length; i=i+1) {

Hmm... the error got escaped;

Source Code:
for (i=0; i</a></a><a .length; i=i+1) {

The fix was (of course) to change it to (for (i=0;i<a.length;i=i+1)). Seems your blog changes your code examples av bit. :(

Zach Leatherman

08 Aug 2008 at 11:02PM

Hey Tom,
Sorry about the code formatter, I don't know quite what it was up to. I think its working now.
Thanks for the tip,
Zach

IMHO, I see little value having seperate namespace generator, usually when you create namespace you dont just call it just "tools" and put it directly under YAHOO, but something unique that will not encounter duplicate, for example

YAHOO.namespace( 'zachleat.tools' ); chances of YUI adding that exact namespace in the future is very unlikely.

Zach Leatherman

30 Sep 2009 at 11:42PM

Yeah, 2007 Zach would have argued with you, but 2009 Zach agrees that he wouldn't put a separate namespace generator into any of his production projects. The extra code weight outweighs the benefit.

Thanks for reading!

Very nice explanation. May be we can also add a check like:

for (i=0; i<a.length; i=i+1) {
if(typeof(a[i]) != "string") continue;
.........
}

so that the loop is skipped if the argument is not of type "string"