Namespacing in JavaScript

Posted on Dec 14, 2011

One of the difficult things when transitioning from a traditional class-based, object-oriented compiled language like ActionScript or Java to JavaScript is that practices that were completely standard are now a matter of debate. Take for example namespacing. In ActionScript it would be completely ordinary and accepted to have a class such as com.rinaldi.portal.turret but in JavaScript, while that is technically possible, it is also both atypical and, apparently, not recommended. However, namespacing is especially important in JavaScript as the dynamic nature of the language and the lack of a compiler can easily lead to collisions. Nonetheless, there are multiple approaches to namespacing in JavaScript and, from what I could gather,no universally accepted standard. In this article, I will discuss what I have learned so far in terms of namespacing approaches and how to avoid variable and functon collisions.

As in my first article on prototype inheritence, remember that I make no claim on being a JavaScript guru. In fact, if you are a JavaScript guru, I’d love to hear feedback to clear up any misconceptions I may have. I am just sharing what I am learning as I go along.

Forgetting What You Know
The first thing I had to get over was my concept of a hierarchical structure of packages and classes. The truth is that even in traditional class-based object-oriented languages like ActionScript and Java, the package hierarchy is more organizational than actual since there is no special relationship between a package and any sub-packages. I needed to let go of the idea of a relationship between a class and a file (or a package and a folder). While you can load as many files as you like via the script tag, there is a cost to loading each, so it is recommended that you don’t needlessly overdo it. In the end, however, there is no actual relationship between files, folders and classes or packages in JavaScript.

So, now that I reminded you about packages, classes and compiler errors, proceed to forget them.

Avoiding Collisions
The main point of namespaces in JavaScript is about avoiding collisions. Keeping in mind that JavaScript is a dynamic language, the following code would run without error:

function load() {
   alert("foo");
}

function load() {
   alert("bar");
}
document.load = load();


If you ran that code within an HTML page, rather than get a runtime error, you would see an alert reading “bar” as the second instance of the function load() overwrote the first. Both instances of the function, because they were not namespaced at all, were added to the global namespace. Adding items to the global namespace is considered bad practice for multiple reasons with the primary reason being that it can easily lead to collisions such as in my example. Especially when you are loading in large external JavaScript files, this can make for exceedingly difficult errors to debug.

Various Methods for Creating Namespaces
While several years old, Peter Michaux wrote one of the best resources I found on the topic of namespacing in JavaScript. He points out several common practices used to help avoid namespace collisions.

Prefix
One that will probably be familiar to many readers is the idea of prefix namespacing as it was the method used by Macromedia in Dreamweaver and other products with their “MM_” namespace such as the MM_swapImage you may have used to do image rollovers in the old skool days of web development. While this method does make it easy to avoid collisions, it doesn’t actually prevent adding items to the global namespace.

Reusing my previous example application whereby I created a Portal Turret class with weapons, to prevent collisions, instead of creating Turret, MachineGun and HeatSeekingMissile, I could have done Portal_Turret, Portal_MachineGun and Portal_HeatSeekingMissiles as follows:

var Portal_HeatSeekingMissile, Portal_MachineGun, Portal_Turret;

Portal_HeatSeekingMissile = (function() {
   function HeatSeekingMissile() {
      …
   }
   return HeatSeekingMissile;
})();

Portal_MachineGun = (function() {
   function MachineGun() {
      …
   }
   return MachineGun;
})();

Portal_Turret = (function() {
   function Turret() {
      …
   }
   return Turret;
})();


While the above code would certainly avoid collisions, it probably looks as ugly to many of you as it does to me. I only imagine it would get uglier the more complex your application became where you might end up with multiple levels of nested prefixes.

Object
The method that I was more comfortable with is the object namespacing, probably because it appears most similar to languages such as ActionScript. Continuing to use my prior example code, in this case I could create a namespace called Portal and place everything under this as follows:

var Portal = {};

Portal.HeatSeekingMissile = (function() {
   function HeatSeekingMissile() {
      …
   }
   return HeatSeekingMissile;
})();

Portal.MachineGun = (function() {
   function MachineGun() {
      …
   }
   return MachineGun;
})();

Portal.Turret = (function() {
   function Turret() {
      …
   }
   return Turret;
})();


This method of namespacing appears to be the most commonly used one that I found across examples though the syntax often varied. Once again, I stuck with a class syntax similar to that generated by CoffeeScript.

Nested Object
While the difference between this example and the one above is actually simply replacing an underscore with a period, it feels much nicer to me. However, as your application gets larger and more complex you might be inclined to mimic a nested hierarchical package structure syntax that will feel comfortable for anyone coming from Java. For example, here I place the MachineGun and Turrets under a Weapons namespace nested inside my Portal namespace:

var Portal = {};

Portal.Weapons = {};

Portal.Weapons.HeatSeekingMissile = (function() {
   function HeatSeekingMissile() {
      …
   }
   return HeatSeekingMissile;
})();

Portal.Weapons.MachineGun = (function() {
   function MachineGun() {
      …
   }
   return MachineGun;
})();


From what I’ve read, while this will work just fine, it isn’t recommended practice as, since JavaScript is a runtime language rather than compiled, there are performance issues with deeply nesting objects like this and few, if any, actual benefits from the practice.

Dynamic Namespaces
One of the major distinctions of JavaScript as compared to languages like ActionScript and Java is that it is dynamic. While this can make the transition from a staticly-typed language challenging, it can also offer certain advantages. If you look at a slightly more recent article on namespacing by Angus Croll, he not only covers the object namespacing I discussed above but also the idea of dynamic namespacing. In this scenario, rather than hard-coding functions onto my namespace (i.e. Portal), I can supply the context dynamically. This means that it would be simple to change the namespace (or context) should you need to (though admittedly, my limited experience has not caused me to need this yet).

Here’s how my example code would look using a dynamic namespace:

var Portal = {};

(function(context) {
   context.HeatSeekingMissile = function() {
      …
   }
   context.MachineGun = function() {
      …
   }
   context.Turret = function() {
      this.machineGun = new context.MachineGun();
      …
   }
   context.Turret.prototype.arm = function() {
      …
   };
})(Portal);


In the above code, simply supplying a different context in the final line would change the namespace for all the functions within. While I like the flexibility, I would need to understand the use-case before I latch onto this method personally as I find it harder to read with all the context references.

Moving Forward
When I started this topic, it seemed relatively simple. I never thought it would require this much research or be a subject of debate. Obviously, JavaScript’s flexibility is both amazing and daunting at the same time. For the moment, I plan to stick with the object namespacing technique as it feels the most comfortable without any major drawbacks. I hope see how it works as I begin to build out some real world applications.

Do you have any namespacing techniques you use in your JavaScript applications? If so, please share your experiences.

Source
http://remotesynthesis.com/downloads/namespace.zip

References:

JavaScript Web Applications by Alex MacCaw

http://michaux.ca/articles/javascript-namespacing

http://javascriptweblog.wordpress.com/2010/12/07/namespacing-in-javascript/

Comments

Sam Farmer Nice article. Partially related, one of the best reasons to write jQuery plugins as opposed to plain JavaScript is that the plugin is always in its own namespace.

Posted By Sam Farmer / Posted on 12/14/2011 at 1:49 PM


michael corbridge Thank you for going through this for us Brian. I appreciate it, and I look forward to delving into javascript.

In your article you refer to var Portal = {} as a namespace, but I would interpret this as defining an object (drawing from my AS3 background). Is there such a concept as namespace in javascript? Again I am drawing upon the ideas of public, private, protected, and internal access control specifiers.

Posted By michael corbridge / Posted on 12/15/2011 at 7:56 AM


Brian Rinaldi Thanks Mike. Yeah, Portal is only a structure but since JavaScript doesn't have the concept of file = class and folder = package, it is the only equivalent, as I understand it, to a namespace that you'd be used to in ActionScript. It does not inherently define access control in any manner either, just to avoid collisions and for organizational purposes.

Also, I should note here, on a separate topic, that Elliot Sprehn posted on my G+ thread that "if you use a decent JS compiler like Closure the namespaces will be compiled away and there's no performance impact."

Posted By Brian Rinaldi / Posted on 12/15/2011 at 12:19 PM


Tony Lukasavage Check out CommonJS. IMO a lot more scalable for modular JS code.

Posted By Tony Lukasavage / Posted on 12/15/2011 at 3:08 PM


Karl Nice series of articles.

I'm in a similar situation. Since Adobe's disastrous announcement in November, I've been scrambling to make sense of HTML application development. The recommended path seems to be:

1. Learn JavaScript

2. Learn other framework(s) which convert to JavaScript, thereby making programming with it less horrendous.

The question is, how to handle step 2? Lots of potential solutions being offered, but no consensus.

Posted By Karl / Posted on 12/18/2011 at 6:54 AM


Brian Rinaldi @Karl - I am specifically avoiding step 2 for the moment. I would never recommend someone learn a language by first learning a framework (unless perhaps they are learning Rails). I knew how to program JavaScript by using frameworks before but I didn't really *know* JavaScript. My goal with this series is to change that.

Posted By Brian Rinaldi / Posted on 12/19/2011 at 8:03 AM


Karl Brian - I don't disagree with you, but it looks like most programmers end up using frameworks to deal with JavaScript's shortcomings.

I wish there were some Sherpas who could help ActionScript programmers make the transition to HTML application development. How, for example, do people minimize the use of magic strings? They're all over the place.

Posted By Karl / Posted on 12/30/2011 at 7:08 AM


Write your comment



(it will not be displayed)







About

My name is Brian Rinaldi and I am the Web Community Manager for Flash Platform at Adobe. I am a regular blogger, speaker and author. I also founded RIA Unleashed conference in Boston. The views expressed on this site are my own & not those of my employer.