Click here to Skip to main content
14,355,411 members

JavaScript Namespace

Rate this:
3.64 (15 votes)
Please Sign up or sign in to vote.
3.64 (15 votes)
14 Oct 2014CPOL
JavaScript Namespace

What is a Namespace

Namespace is a container for set of identifiers, functions, methods and all that. It gives a level of direction to its contents so that it will be well distinguished and organized.

Why is Namespace Needed

Namespace we must have known from any language or the other. What it does is, it doesn’t allow us to pollute our code base and makes it cleaner by grouping our code logically and avoiding unexpected and expected collision.

To achieve this, what we need to do is to create a namespace in application and use it.

In any modern day application, Namespace is a must to have because at the end, we need third party libraries and components.

Importance of Namespace in JavaScript

Unfortunately JavaScript doesn’t provide namespace by default. So anything (function, method, object, variable) we create in JavaScript is global and we continue polluting that global namespace by adding more to that.

But the good news is that we can create namespace in JavaScript and that too very easily.
As we know, in JavaScript everything is an object and creating an object is very simple. We can achieve namespace very easily with some minor tweaks.

Let's See How JavaScript Makes All Things Global

 //declare a function
function calculateTax(item) {
    return item.price * 1.40;
}
 
var product = function (cost) {

   this.cost = cost;
   this.getCost = function(){
      return this.cost;
   };
};
 
function doTaxCalculations() {

    var p = new product(100);
    alert(calculateTax(p.getCost()));
}

In the above code, the two functions and the class, all three are settled down in the global space.
It's a simple code base but it contains 3 global items (calculateTax, product, doTaxCalculations).
These three will really put us in trouble if we are using 3rd party libraries and they also contain the same name.
Like if it is used before other library, it will be overridden by Library and vice versa.

JavaScript Sample Namespace

In JavaScript, it is nothing but a single global object which will contain all our functions, methods, variables and all that. Here ‘MYAPPLICATION‘ is acted as a JavaScript namespace and the only global object which contains all other items.

var MYAPPLICATION = {
    calculateTax: function (item) {
        return item * 1.40;
    },
    product: function (cost) {
        this.cost = cost;
        this.getCost = function(){
                          return this.cost;
                       };
    },
    doTaxCalculations: function () {
        var p = new MYAPPLICATION.product(100);
        alert(this.calculateTax(p.getCost()));
    }
}

To access any of the methods or variables, you need to fetch it through the MYAPPLICATION.

var newProduct = new MYAPPLICATION.product(200);
alert(p.getPrice());

Not only single namespace like the above one, but we can create nested JavaScript Namespace as well.
Let's look at a sample of nested JavaScript Namespace.

Nested JavaScript Namespace

It is nothing but a namespace inside a namespace, which provides better modularization for complex JavaScript application.

var MYNESTEDAPPLICATION = {

    MODEL: {
        product: function (price) { 
			         this.price = price; 
			        this.getCost = function(){
			             return this.price;
			         };
			     }
    },
    LOGIC: {
        calculateTax: function (item) {
            return item * 1.40;
        },
        doCalculations: function () {
            var p = new MYNESTEDAPPLICATION.MODEL.product(100);
            alert(this.calculateTax(p.getCost()));
        }
    }
}

Note

Do your naming convention in such a manner that it will be self explanatory and 
not conflict other Library. May be I am not that good at those.

Create Namespace If It Does Not Exist

Like the above, we use a single global object, but it might conflict with other global.
To avoid this, we can check the existence before creating it and it is a good practice.

// not safe, if there's another object with this name we will overwrite it
var MYSAMPLEAPP = {};
 
// We need check before we create the namespace
if (typeof MYSAMPLEAPP === "undefined") {
    var MYSAMPLEAPP = {};
}
 
// shorter version
var MYSAMPLEAPP = MYSAMPLEAPP || {};

The above one is the safest way to create namespace, but what we can do is we can make it more easy by writing a function which will create our namespace.

Function To Create Namespace

We just need to call a simple function with some arguments to create our namespace. Then, we can define all functions and variables in that namespace.

var MYNAMESPACE = MYNAMESPACE || {};
 
var newNamespace = MYNAMESPACE.createNameSpace("MYNAMESPACE.COUNTRY.STATES");
 
newNamespace.product = function(price) {
	this.price = price;
	this.getCost = function(){
	return this.price;
	}
};

MYNAMESPACE.createNameSpace = function (namespace) {
	
	//get the namespace string and split it
    var namespaceArr = namespace.split(".");
    var parent = MYNAMESPACE;
 
    // excluding the parent
    if (namespaceArr[0] === "MYNAMESPACE") {
        namespaceArr = namespaceArr.slice(1);
    }
 
    // loop through the array and create a nested namespace 
    for (var i = 0; i < namespaceArr.length; i++) {

        var partname = namespaceArr[i];

        // check if the current parent already has the namespace declared
        // if it isn't, then create it
        if (typeof parent[partname] === "undefined") {
            parent[partname] = {};
        }

        // get a reference to the deepest element in the hierarchy so far
        parent = parent[partname];
    }
    //  empty namespaces created and can be used.
    return parent;
};

Basically, the createNameSpace function splits the string and creates a nested namespace from it.

<code>MYNAMESPACE.createNameSpace("MYNAMESPACE.COUNTRY.STATES");</code>

Output

var MYNAMESPACE = {
    COUNTRY: {
        STATES: {
        }
    }
}

Namespaces Aliasing

We can achieve this by simply aliasing the namespace in a local variable:

var state = MYNAMESPACE.COUNTRY.STATES;

Use state instead of the whole namespace to fetch all the variables and functions.

Note

However, the above solution regarding namespace is perfectly valid and useful for most cases.
But there might be some cases where this isn’t the best choice to make.
Here, there is only single global instance but nothing stops us from accessing the inner variables directly.
Somehow, we need to control the access to the private variables. This can be achieved by “Creating modular application using modules” that will encapsulate date.

Using Module

MYAPP.MODEL.PRODUCTS.product = function(cost) {
    
    //cost is the private variable
    var cost = cost;   
    return {
        isTaxable: true,
        getCost: function(){                                               
            return cost;                                            
        }
    };
};

cost accessible to the function because of closure else it is not accessible directly.
isTaxable and getCost are public ones.

There are many patterns to achieve this.
Like making everything private and exposing what we need to expose.

MYAPP.MODEL.PRODUCTS.product = function(cost){

  //everything  private
    var cost = cost;    
    var isTaxable = true;
    var getCost: function(){                                               
            return cost;                                            
        };
 	//expose what you need
    return {
        isTaxable: isTaxable,
        getCost: getCost
    };
};

Though there may be some security issues in the above written samples, we can make it more and more perfect.
We can prevent the access by reference to any variable inside the namespace. The are lot more patterns we can follow to achieve this.

Conclusion

The use of Namespace makes the JavaScript code modular and structured also easy to read, understand and modify. So without polluting the global namespace, we can achieve all these things, any way we have to use the global namespace but we are not messing things there.

Hope this helps. Thanks for reading.

Image 1 Image 2

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

_debasis
Software Developer
India India
Software Engineer | Blogger | Reader| Music Lover | Cook | Traveler | Foodie

Comments and Discussions

 
QuestionCorrection to code Pin
Alexandru Matei26-Feb-16 3:41
memberAlexandru Matei26-Feb-16 3:41 
GeneralMy vote of 1 Pin
echosteg.com6-Oct-15 3:31
memberechosteg.com6-Oct-15 3:31 
GeneralMy vote of 1 Pin
Ramsu8-Aug-15 10:08
memberRamsu8-Aug-15 10:08 
QuestionCopied Article - Write your own buddy, don't steel others work please Pin
Ramsu8-Aug-15 10:06
memberRamsu8-Aug-15 10:06 
GeneralMy vote of 1 Pin
XKaleshX8-Dec-14 20:23
memberXKaleshX8-Dec-14 20:23 
GeneralMy Vote 5 Pin
Shemeemsha (ഷെമീംഷ)29-Oct-14 21:12
memberShemeemsha (ഷെമീംഷ)29-Oct-14 21:12 
GeneralMy vote of 5 Pin
Prasad Khandekar24-Oct-14 6:27
professionalPrasad Khandekar24-Oct-14 6:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Article
Posted 14 Oct 2014

Tagged as

Stats

68.2K views
13 bookmarked