Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Namespaces in JavaScript

4.72/5 (26 votes)
1 Jun 20076 min read 4   821  
Extending JavaScript to handle namespaces, classes, static methods, and global namespace variables.

Introduction

I decided to write this tutorial because I found a clever way to create namespaces in JavaScript. In the process of creating namespaces, I found several ways of extending JavaScript to handle constructed classes, class objects, static methods and global namespace objects.

JavaScript is actually capable of almost everything C# can do, but you have to think outside of the box to create it. You must be asking yourself, "you can do all that with a function method?"... Yes! Functions are both methods and objects. In JavaScript it is fairly simple to create an object.

JavaScript
var obj = new Object();

or in JSON

JavaScript
var obj = {} 

Objects are all we need to create object oriented namespaces. Below is the main code for creating namespaces. It is very small and simple, but has a lot of structuring power. Now you may ask yourself "why would I want to make my code longer on the client side?", well more and more people are moving to interactive websites that work with AJAX which has lots of complicated clientside JavaScript that needs structuring.

Below is a list of pros and cons for implementing namespaces.

Pros

  1. Structure
  2. Object Oriented Names
  3. Easy to Remember
  4. Unique Variables and Methods
  5. Custom Branding
  6. Integration with Future Web 2.0 Sites

Cons

  1. Longer Code
  2. Loading Time
  3. Too Complex

Well the pros outweigh the cons, plus most of the cons can be fixed too. For example, the longer code can be shorthand using aliases which I will describe later in this tutorial. Loading time can also be resolved with shorthand code; besides more people are moving to high-speed broadband and getting off the dialup connections. Another way is loading JavaScript on demand using AJAX, this will cut down on initial load times. The third issue "Too Complex!", well, have you every opened up someone's JavaScript and tried to makes sense of it right from the get go? It's very easy to get lost in code execution. So I ask you which is easier to understand? var sObj is an object or System.Object is an object.

Let's move on now and learn about my code and how it will help you get organized. Below is the actual namespace code for creating namespaces.

Code

JavaScript
var Namespace =
{
    Register : function(_Name)
    {
        var chk = false;
        var cob = "";
        var spc = _Name.split(".");
        for(var i = 0; i<spc.length; i++)
        {
            if(cob!=""){cob+=".";}
            cob+=spc[i];
            chk = this.Exists(cob);
            if(!chk){this.Create(cob);}
        }
        if(chk){ throw "Namespace: " + _Name + " is already defined."; }
    },

    Create : function(_Src)
    {
        eval("window." + _Src + " = new Object();");
    },

    Exists : function(_Src)
    {
        eval("var NE = false; try{if(" + _Src + "){NE = true;}else{NE = false;}}catch(err){NE=false;}");
        return NE;
    }
}

Using JSON, I predefine a variable as an object with three methods.

  • Namespace.Register()
  • Namespace.Create()
  • Namespace.Exists()

Namespace.Register allows you to register namespaces globally in your page. You pass a dot name string parameter to it like this:

JavaScript
Namespace.Register("System.Data");

This registers System.Data for use and creates the namespaces System and System.Data because it is a dot notation hierarchy. The Register method checks to see if the final dot name is already defined. If it is defined it will throw an error and if it is not, it will register it. The method Namespace.Create() uses the eval method to create a global object in the current window with that dot name.

Implementation

Now let's see how this code can be effective in a hello world example. In my example I have 4 files.

  1. namespace.js
  2. using.js
  3. helloworld.js
  4. example.html

Namespace.js contains the sourcecode above which we already described, so let's move to the next. Using.js is our declaration file for declaring our namespaces. The code looks like this.

JavaScript
Namespace.Register("System.Classes.HelloWorld"); 

I put this in a separate js file because you will usually have multiple definitions. We register the namespace System.Classes.HelloWorld which registers System, System.Classes and System.Class.HelloWorld. The next file helloworld.js contains our classes, methods and variables. It looks like so.

JavaScript
// Class Example
System.Classes.HelloWorld = function(){ return {
 Message : "Hello World!",
 Hello : function()
        {
  alert(this.Message);
        }
};}
//PreConstructed class with methods
System.Classes.HelloDevelopers = {
 Message : "Hello Developers",
 Message2 : "Hello Developers Again",
 Message3 : "Wassup!",

 Hello : function()
 {
  alert(this.Message);
 }
}
//Static Method
System.Classes.HelloMom = function()
{
 var Message = "Hi";
 var Message2 = "Mom!";

 alert(Message + " " + Message2);
}
//Global Namespace Variable
System.Classes.Hey = "Hey";

The first class System.Classes.HelloWorld contains one variable Message and one method Hello() It is not constructed because we have wrapped it in a function() and made it return the JSON object. This is the key to creating non constructed class objects.

The second class System.Classes.HelloDevelopers is a preconstructed class. It contains 3 variables Message, Message2, Message3 and 1 method Hello() Notice the function is removed and there is no return. It is actual ready to use and needs no construction. Another thing to point out is, we have two Hello() named methods in this file without collision. Since they are in different namespaces they can co-exist.

The third System.Classes.HelloMom is a static method. It is ready to use because it is in a function wrapper with no JSON.

Fourth System.Classes.Hey is a string variable added to one of the namespaces. It is a way of adding a var to a page without global naming collision. As you can see with the code we do not declare any vars to the namespaces. They are predefined as objects, variables or methods and ready to use. Now let's move on to using the code.

Our next file example.html contains the calls and construction of the classes and methods. Inside looks like this:

JavaScript
<html>
<head>
<script type="text/javascript" src="namespace.js"></script>
<script type="text/javascript" src="using.js"></script>
<script type="text/javascript" src="helloworld.js"></script>
</head>
<body>
<script type="text/javascript">
//Construct a class and call a method------------
var HW = new System.Classes.HelloWorld();
HW.Hello();
//-----------------------------------------------
//Use a PreConstructed class and call a method---
System.Classes.HelloDevelopers.Hello();
//or
var HW2 = System.Classes.HelloDevelopers;
HW2.Hello();
//-----------------------------------------------
//Static Method Call from class------------------
System.Classes.HelloMom();
//-----------------------------------------------
//Using variables from class---------------------
alert(System.Classes.HelloDevelopers.Message3);
//-----------------------------------------------
//Using variables from a namespace---------------
alert(System.Classes.Hey);
//-----------------------------------------------
</script>
</body>
</html>

We insert the scripts at the top to include namespace, using, and helloworld. This needs to stay in order due to execution and creation. Next we construct an unconstructed class object and call one of its methods.

JavaScript
var HW = new System.Classes.HelloWorld();
HW.Hello();

As you can see we assign a var and use new to construct it. We then call hello world which will popup an alert with the message. This brings us to aliases. Notice now we have a var HW instead of System.Classes.HelloWorld(). This is smaller and easier to manage than the full dot notation, but holds all the class methods and variables.

The second thing we use is a pre constructed class. Which we can either use with the full dot notation System.Classes.HelloDevelopers.Hello() or alias shorthand:

JavaScript
var HW2 = System.Classes.HelloDevelopers;
HW2.Hello();

Both ways call the method. Notice we do not use the new keyword to construct because we predefined it.

The next piece of code is a static method call which is also ready to use. Just call it by name to fire the method with no construction.

JavaScript
System.Classes.HelloMom()

Once a class is pre constructed or constructed you can use its properties or methods. This brings us to the next line of code:

JavaScript
alert(System.Classes.HelloDevelopers.Message3);

This is getting the message3 string property from the System.Classes.HelloDevelopers class and popping it up in an alert.

The last but not least piece of code is the global namespace string variable System.Classes.Hey.

JavaScript
alert(System.Classes.Hey);

This is a way of using variables in the namespace scope without having them collide with other global vars.

Conclusion

Wow, OO in JavaScript, simply AMAZING! I hope you enjoyed this tutorial as much as I did creating it. Later...

Terms and Conditions For Use, Copy, Distribution, and Modification

THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS CODE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here