Organizing Javascript codes from a C# perspective using namespaces

Recently I had been writing a lot of Javascript codes and was very unhappy about the code organization and the architect of my source code. Having lots of functions all jumbled up with UI logic and business logic was getting me no where. I decided to stop all my coding and search for a better way to organize my javascript codes.

I saw some solutions by using 3rd party javascript libraries such as YUI and Microsoft Ajax Client library to name a few. It did provide a great way to solve my problems, but what if I wanted to distribute my Javascript codes as an SDK for other devs to build upon (like the Facebook Javascript SDK). They would have to reference it, and even learn how to use YUI or MSAjax libraries. I wanted simpler solution less bulky solution.

Then after searching around, I found out a lot of ways to do it. I have broken up this tutorial into various parts which I will be posting soon. The first one is using the concepts of namespaces as you would do in C#.

Lets say I want to create a SDK called MySDK. I would want to have it under the company’s name like CompanyName.MySDK.

In C# you would do it as …

namespace Prabir.Shrestha
{
   public MyClass
   {
   }
}

 Equivalent code for Javascript would be as follows:

var Prabir = Prabir || {};
Prabir.Shrestha = Prabir.Shrestha || {};
Prabir.Shrestha.MyClass = function(){
};

Lets examine the first line in details. var Prabir tells us to create a Javascript variable called Prabir. The right hand side tells to assign Prabir (rhs) to Prabir (lhs) and if Prabir(rhs) is not defined create a new object and assign it to Prabir (lhs) – counfusing isn’t it. Well just remember it as a sort of C# null coalescing operator (??). The next line does the similar thing. It is very important to check if the object already exists as you might have another SDK under the same namespace, and if you create a new one it would override the old variable, so only the last referenced SDK would be available.

Note: Put var only in the root namespace lines and not in others.

So now you could create public functions using the following code.

var Prabir = Prabir || {};
Prabir.Shrestha = Prabir.Shrestha || {};
Prabir.Shrestha.MySDK = function(){
     return {
          public_method : function() {
               alert('I am a public method');
          }
     };
};

To call the public method you would need to create an instance of the object as you would do in C# and call the function.

var mySdk = new Prabir.Shrestha.MySDK();
mySdk.public_method();

Congrats. That’s the first way to organize your Javascript using namespaces as in C#.

To make it more easy, I actually landed up creating a new Javascript library to make managing namespace easier. You can find this library at http://github.com/prabirshrestha/js-namespace

/*!
 * js-namespace Javascript Library v1.0
 *
 * http://www.prabir.me
 * http://github.com/prabirshrestha/js-namespace
 *
 */
NS = {
    register: function(ns,container){
        var root = container || window;
        var nsParts = ns.split('.');
        var length = nsParts.length;
        for(var i = 0; i < length; ++i)
            root = root[nsParts[i]] = root[nsParts[i]] || {};
        return root;
    },
    exists: function(ns,container){
        var root = container || window;
        var nsParts = ns.split('.');
        var length = nsParts.length;
        for(var i = 0; i < length; ++i){
            if(!root[nsParts[i]])
                return false;
            root = root[nsParts[i]];
        }
        return true;
    }
};
// alias
NS.r = NS.register;
NS.e = NS.exists;

To create a namespace you would call the register method.

NS.register('Prabir.Shrestha');

and to check if the namespace exists call the exists function. Instead of using NS.register and NS.exists you could also use the shorthand NS.r and NS.e respectively.

The uncompressed file is 900 bytes and the minimized gziped file is around 368 bytes.

Next tutorial is about Object Oriented Programming in Javascript. So stay tuned.

js-namespace-samples.zip (1.92 kb)


blog comments powered by Disqus