What is the Problem?

JavaScript isn’t always the easiest language to use in a class based manner. While there’s a number of reasons for this, I’m going to solve one of the more annoying problems here today.

That problem is namespaces. In class based programming it’s a good idea to namespace your classes. That way if your project uses two different code packages that both have a class named Shape you don’t have them overriding each other. That’s because one package attached all their classes to the namespace mynamespace and the other to anotherns which means that there actually is no Shape class, but instead theres a mynamespace.Shape class and a anotherns.Shape class. Namespaces are usually very proprietary to keep them unique and keep conflicts down. This can even be done multiple levels deep for organizational purposes; ex: com.mynamespace.Shape

This is a good system. Except...in JavaScript it’s a bit clunky. See, in JS that’s not an intended native functionality...it’s just a way we happen to use the language to fake it (we make objects and attach our “classes” to them as properties). So therefore while other languages have good ways to deal with namespaces, JS doesn’t (at least nothing cross-browser yet). That leads to having to type out the entire namespace and class name each time you utilize a class. In many other languages you can just do something like import com.mynamespace.ClassName; and then forevermore be able to just refer to the class name itself such as var a = new ClassName(); (because you’ve specified which class you want to be the one used globally). Or likewise you can use entire packages like import com.mynamespace.*; and use every class with that namespace for simpler usage. But in JS we’re just kinda stuck going var a = new com.mynamespace.ClassName(); to instantiate or com.mynamespace.ClassName.staticMethod(); to utlize static methods, etc. One example of this that I’ve found particularly annoying is using the CreateJS package of classes. For every instance I make or static anything I access I’ve got to type createjs. all over again...and I forget to a lot.

The Solution

The solution is a little function I wrote that takes care of this. You can basically call it on classes with namespaces and then just use the class name from then on. It’s as simple as use_namespace("com.namespace.ClassName"); and then you can use new ClassName() or access ClassName.staticvar all you want.

Not only that, but it supports the * wildcard. So if you want to use all of createjs at once just use use_namespace("createjs.*"); and now Stage, Shape, Tween etc are all easy to use.

It also has a neat feature where if you’ve got 2 same class names in different namespaces you can use them both and give a nickname to one of them. For example if you’re already using a Shape class and you want to use another one you can use use_namespace("com.namespace.Shape", "OtherShape"); and now you can instantiate new OtherShape() to access that particular class.

Without further ado here’s the function in semi-readable form:

// Free under MIT License | for info: http://mbmedia.cc/stuff/use_namespace
function use_namespace(ns,cl,g)
    "use strict";
    g = g || window;
    var a = ns.split('.');
    if (a.length == 1) return;
    var l = cl || a[a.length-1];
    var m = a.pop();
    var b = g[a.shift()];
        b = b[a.shift()];
    if (l !== '*')
        g[l] = b[m];
    else {
        for (var c in b)
            g[c] = b[c];

and in more mini-form:

// Free under MIT License | for info: http://mbmedia.cc/stuff/use_namespace
function use_namespace(ns,cl,g){"use strict";g=g||window;var a=ns.split('.');if(a.length==1)return;var l=cl||a[a.length-1];var m=a.pop();var b=g[a.shift()];while(a.length>0)b=b[a.shift()];if(l!=='*')g[l]=b[m];else{for(var c in b)g[c]=b[c];}}

Yes, you must leave the comment there when you use it. Why? Simple: because I want this to spread and become common. Because when that happens code package builders can start using more complex namespaces with better organizational patterns which leads to being able to do more stuff easily...and technically that could change JavaScript for the better all around. So when someone sees some code with all this use_namespace stuff and finds the function I want them to be able to go here and learn about it and use it! It’s just a comment in the code, and leaving in the comment header is pretty standard for MIT license stuff...so that shouldn’t hinder you at all in using it.

More Info

  1. Note that the original namespace usage is still available, it doesn’t remove it. After using this you can access the class the short or long ways.

  2. Notice there’s a third argument. That’s for manually determining the global object. Not all environments use window, so if yours doesn’t then you can manually supply your global object via the third argument.

  3. Keep mind that this is to be used by end users of large code packages, not necessarily creators of them. If you call this function in your code package then you’re basically as good as un-namespacing all your classes for anyone who uses your code lib. Only THEY know which classes they want to access in such a global fashion! You can’t do it for them, that defeats the purpose!