Tuesday, May 3, 2011

javascript namespace

Javascript namespace is nothing but actually a global object and all other variables, functions, objects are placed in this object, so they become properties of the global object.

Code below creates two global objects:

// we have two global objects
var Category = {
     name:'books', 
     description:'all books',
     getName : function(){return this.name;},
};
var Product = {};


Now let's introduce namespace, so everything is into MyProject namespace, and MyProject is the only global variable.

var MyProject =  MyProject || {};
MyProject.Modules = MyProject.Modules || {};
MyProject.Modules.Category = {
     name:'books',
     description:'all books',
     getName : function(){return this.name;},
};
MyProject.Modules.Product = {};


What if we want to use constructor function? We can still do that:

MyProject.Models.Car = function(model) {
       this.model = model;
}
var newCar = new MyProject.Models.Car('toyota');


It is tedious every time we declare a new namespace, we have to do something like

MyProject.Modules =  MyProject.Modules || {};


Let's create a general purpose namespace function

var MyProject= MyProject || {};
MyProject.ns = function (nsName) {
     var parts = nsName.split('.'),
     parent = MyProject,
     i;
    // strip redundant leading global
    if (parts[0] === "MyProject") {
         parts = parts.slice(1);
    }
    for (i = 0; i < parts.length; i += 1) {
          // create a property if it doesn't exist
         if (typeof parent[parts[i]] === "undefined") {
             parent[parts[i]] = {};
         }


         parent = parent[parts[i]];
    }
return parent;
};


Now, we have a general purpose namespace function. How to use it? At top of your javascript file, declare the namespace using this function.

//in file MyProject/Models/Car.js
MyProject.ns('Models');
MyProject.Models.Car = {};

//in file MyProject/Modules/Products/Kindles/Wifi.js

MyProject.ns('Modules.Products.Kindles');
MyProject.Modules.Products.Kindles.Wifi = {};


Well, if we think the prefix MyProject.Modules.Products.Kindles is too long, we can simply do

var ns = MyProject.ns('Modules.Products.Kindles');
ns.Wifi = {};


In extjs, declaring a namespace is simple as Ext.ns('SomeNamespacesStringWithDotConnection'); 



Basically that is the whole idea of javascript namespace. Actually, JavaScript doesn’t have namespaces built into the language syntax, unlike java or PHP5.3. But the key is, javascript's object (function is object as well) can provide local scope, so just put everything into your own object, and you can achieve namespace feature.

No comments: