There are many ways to safely namespace your objects in JavaScript. This article discusses common practices I have seen.

Prefix Namespacing

If the goal of namespacing is to avoid collisions. The following system is just as likely to avoid namespace collisions as any other system as long as we know the global variable name prefix myApp_ is unique.

// add uniquely named global properties var myApp_sayHello = function() { alert('hello'); }; var myApp_sayGoodbye = function() { alert('goodbye'); }; // use the namespace properties myApp_sayHello();

C programs frequently use prefix namespacing. In the JavaScript world, you may have encountered Macromedia's MM_ functions like MM_showHideLayers .

I think that prefix namespacing is the most clearly understandable namespacing system in JavaScript. (The object namespacing strategies below can cause confusion when the keyword this becomes involved.)

Prefix namespacing does create many global objects. This is not a problem in regard to namespace collisions as the prefix protects against that. The problem with prefix namespacing is some web browsers (e.g. Internet Explorer 6) perform poorly if there are many global objects, so I am told. I ran some tests and there was a little thread on comp.lang.javascript but I didn't peruse this topic completely.

Single Object Namespacing

Currently, the most popular JavaScript namespacing practice is using a single global variable to reference an object. That referenced object then references your "real business" and because your global object is named uniquely then your code should run happily with anyone else's code present.

If you are pretty sure no one in the world has used the global variable name myApp then you may have code like this

// define the namespace object var myApp = {}; // add properties to the namespace object myApp.sayHello = function() { alert('hello'); }; myApp.sayGoodbye = function() { alert('goodbye'); }; // use the namespace properties myApp.sayHello();

When the the last line of code above runs, the JavaScript interpreter first finds the myApp object, then finds and calls that object's sayHello property.

A problem with object namespacing is it leads to confusion with object-oriented message passing. There is no obvious syntactic difference between

namespace.prop();

and

receiver.message();

Looking at this confusion more carefully we have the following for the namespace concept. Suppose we have the following library.

var myApp = {}; myApp.message = 'hello'; myApp.sayHello = function() { alert(myApp.message); };

The code using this library is free to write.

myApp.sayHello(); // works var importedfn = myApp.sayHello; importedfn(); // works

Compare this to the confusing message passing version which uses this .

var myApp = {}; myApp.message = 'hello'; myApp.sayHello = function() { alert(this.message); };

The code using this library is free to write.

myApp.sayHello() // works because "this" refers to myApp object. var importedfn = myApp.sayHello; importedfn(); // error because "this" refers to global object.

The lesson to be learned here is that this should never refer to an object being used as a namespace because it leads to confusion about importing identifiers from that namespace. This problem is one of the reasons that this makes my list of JavaScript Warning Words

(This also suggests that a library's API properties should point to the same function so that these functions can be imported into other spaces. This problem was pointed out in the comments of my Lazy Function Definition Pattern article. The lazy function definiton can be used safely when hidden within a library and is not part of the API.)

Nested Object Namespacing

Nested object namespacing is another common practice which extends the idea of object namspacing. You may have seen code like the following

YAHOO.util.Event.addListener(/*...*/)

Resolving the above line requires the interpreter to first find the global YAHOO object and then its util object and then its Event object and then find and call its addListener property. This is way too much work each time an event handler is attached to a DOM element so the concept of importing is used.

(function() { var yue = YAHOO.util.Event; yue.addListener(/*...*/); yue.addListener(/*...*/); })();

If you know that the YAHOO.util.Event.addListener function does not use the this keyword and always references the same function then the importing could be even more compact.

(function() { var yuea = YAHOO.util.Event.addEventListener; yuea(/*...*/); yuea(/*...*/); })();

I think nested object namespacing is unnecessarily complex when the goal is simply avoiding identifier collisions. Is Yahoo! not confident that the global identifiers YAHOO_util_Event and YAHOO_util_Event_addEventListener are unique?

I think the motivation for nested object namespacing is to have the appearance of the Java package naming convention which in Java is inexpensive. For example, in Java you may see the following.

package mytools.text; class TextComponent { /* ... */ }

A fully qualified reference to the class above would be mytools.text.TextComponent .

The following package naming description is in Learning Java by Niemeyer and Knudsen.

Package names are constructed hierarchically, using dot-separated naming convention. Package-name components construct a unique path for the compiler and runtime systems to locate files; however, they don't create relationships between packages in any other way. There is really no such think as a "subpackage"; the package namespace is, in actuality, flat—not hierarchical. Packages under a particular part of the package hierarchy are related only by convention. For example, if we create another package called mytools.text.poetry (presumably for text classes specialized in some way to work with poetry), those classes won't be part of the mytools.text package; they won't have the access privileges of package members.

The illusion of nested namespaces in Perl exists also. In Perl, the nested package names are separated by double colons. You may see Perl code like the following.

package Red::Blue; our $var = 'foo';

A fully qualified reference to the above variable would be $Red::Blue::var .

In Perl, like Java, the idea of a namespace hierarchy is only for the benefit of the programmer, not the language. Programming Perl by Wall, Christiansen and Orwant explains

The double colon can be used to chain together identifiers in a package name: $Red::Blue::var . This means the $var belonging to the Red::Blue package. The Red::Blue package has nothing to do with any Red or Blue packages that might happen to exist. There is, a relationship between Red::Blue and Red or Blue may have meaning to the person writing or using the program, but it means nothing to Perl. (Well, other than the fact that, in the current implementation, the symbol table Red::Blue happens to be stored in the symbol table Red . But the Perl language makes no use of that directly.)

The parenthetical note at the end of the above quotation implies that Perl may have the same identifier resolution cost that using nested namespace objects in JavaScript has. If the Perl implementation changes the cost could disappear. In JavaScript, I believe that the cost of nested object namespacing will never go away because JavaScript uses late-binding.

I don't think nested object namespacing in JavaScript provides any significant benefit but it is potentially very expensive at runtime if importing is not used.

A compromise

If pure prefix namespacing really is slow in some browsers, and the concept of nested namespaces helps keep things organized in the developer's mind then I think the Yahoo! example above could be written as either

YAHOO.util_Event_addListener

or with a few more globals (but still not many for any give page)

YAHOO_util_Event.addListener

Namespacing in which dimension?

Perl CPAN modules are namespaced based on what they do. For example, I wrote a module in the namespace

JavaScript::Minifier

If someone else writes his own module with the same name, and he unknowingly uses the CPAN module by the same name through some module dependency, then a collision occurs.

Java programmers takes the most verbose, but safest, approach, of course. (Java programmers seem to think about code running in huge systems.) In Java, packages are generally namespaced based on both who wrote it and what it does. (A formalization of the myFunc style.) The "who wrote it" part even uses a relatively guaranteed unique name that the developer "owns". If I wrote a Java minifier, it would use the following namespace since I own the michaux.ca domain name.

ca.michaux.javascript.minifier

In JavaScript, after the results of this discussion, this could be written more efficiently as

ca_michaux_javascript_minifier

Because JavaScript is served as text, this sort of namespacing seems too expensive by increasing download time. Gzip compression finds common strings and replaces them with a small string. If gzip is not available then importing could be used.

var ca_michaux_javascript_minifier = {}; (function() { var cmjm = ca_michaux_javascript_minifier; // refer to cmjm inside this module pattern })();

I'm not suggesting that these long namespaces are necessarily necessary but they are definitely the safest in avoiding namespace collisions.

Other Namespacing Issues

Identifiers are not only created in JavaScript source. The name attribute of a form is added to the document.forms object. It makes sense to namespace these with <form name="myCompany_login"> .

Namespacing class name attributes like <div class="myCompany_story"> could be worthwhile also to reduce CSS namespace collisions and when JavaScript code is searching for DOM elements by class name.

Summary

Personally I think that anything like YAHOO.util.Event.addListener , with dots or underscores, is overly paranoid of collisions. It could have been just YUI.on . Dojo provides enough protection with dojo.connect for the same job because it covers the "who" and "what" dimensions of namespacing sufficiently. No one in their right mind is going to come along and write a JavaScript library under the namespace dojo . The Dojo developers will not forget they already have a connect function and write another one.

It might be good if we had a website where programmers could reserve their JavaScript globals identifiers, underscore prefixes and when ECMAScript 4 is released also their package names: "The JavaScript Namespace Registry".

JavaScript is a powerful language with a minimal set of concepts. Even though JavaScript doesn't have language-level support specifically designed for avoiding namespace collisions, there are several ways to solve the problem. There is no one "right" answer. Pick the system you like best.

But please, whatever you do, just don't put another global $ identifier out there!

Extras

comp.lang.javascript discussion on namespacing

Update August 9, 2008 The Linux folks have a namespace registry: LANANA.