Categories
Archives
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- April 2007
- March 2007
- February 2007
- January 2007
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
Dreaming the Right Dreams | Home | Getting started with PDO_MSSQL
Filed under Quick Tips on June 6, 2008 by Alex MelmanAn Easy Way to Implement Namespaces in JavaScript
(Object-Oriented JavaScript Series)Namespaces are a great way to uniquely distinguish objects from different projects. Unfortunately, JavaScript does not have native support for namespaces, but we can approximate it, by putting our objects inside other empty objects.
For example, to create a namespace called arc90.components, we would first define arc90 as an empty object:
arc90 = {}
If an object called arc90 already exists, we don't want to erase it; so we will check for it first, then create an empty object only if the arc90 object doesn't already exist. We can do that like so:
if (typeof(arc90) == "undefined")
arc90 = {}
The type of operator returns the type of an object as a string. If the object does not exist at all, a value of "undefined" will be returned. This is what we are checking for:
Now that arc90 is defined as an object, we can go ahead and define the next level of the namespace, arc90.components. We basically repeat what did for the arc90 part of the namespace:
if (typeof(arc90.components) == "undefined")
arc90.components = {}
By now, you must be thinking, "Boy, we're repeating a lot of code here. There must be an easier way." Well, don't worry, there is. There are two options. You can use the YUI Library, which already contains a namespace function, or we can create a simple namespace function ourselves. Since I don't want my tip to consist of just a link to Yahoo!, I will do things the long way and show you how to create a namespace function.
The most important part of the function is the use of the eval operator. This lets you pass in JavaScript code as text, allowing you to dynamically create object names. This is important, because normally, object names must be hard-coded, which would prevent us from creating new objects dynamically, if not for the eval operator.
Now, we will create a function, which will create a namespace object out of the string you pass in. For example, calling:
createNamespace("arc90.components");
will create an object called arc90.components. It also returns the object that was created, so that you can create an alias. For example, calling the function this way:
var alias = createNamespace("arc90.components");
will create the namespace object and set alias to reference the same value. Now, if we were to define a new object called Checkbox within the namespace, we can either use the fully qualified name, like so:
arc90.components.Checkbox = function() {}
or we can use the alias:
alias.Checkbox = function() {}
You can use either the fully qualified namespace or the alias to reference the same objects. The only thing you must be aware of is that you cannot give your alias the same name as any part of the namespace. For example, if you have a namespace called arc90.components, you cannot name your alias arc90, or components. This will overwrite the object in the original namespace.
Now, let's create the createNamespace function:
function createNamespace(ns)
{
// First split the namespace string separating each level of the namespace object.
var splitNs = type.split(".");
// Define a string, which will hold the name of the object we are currently working with. Initialize to the first part.
var builtNs = splitNs[0];
for (i = 0, i < splitType.length; i++)
{
// Add the next part of the namespace only if we are at the second level or further.
builtNs += (i > 0) ? ("." + splitType[i]) : "";
// Check if the object we want to add exists, and add a new empty object if it doesnt.
eval(builtNs + " = typeof(" + builtNs + ") =='undefined' ? {} : " + builtNs + "; ");
}
return eval(ns); // Return the namespace as an object.
}
The above code first splits the namespace string into parts, so that a namespace called arc90.components will be split into two strings, arc90, and components. The function then loops, adding the next string to the first as it goes. On the first iteration, we have only arc90, which will then be created as an object by the line:
eval(builtNs + " = typeof(" + builtNs + ") =='undefined' ? {} : " + builtNs + "; ");
This is essentially the same code we wrote at the beginning, rewritten using a one-line ternary operator, and wrapped in an eval statement. After the eval statement runs, the code generated would look like this (on the second iteration):
arc90.components = typeof(arc90.components) == 'undefined' ? {} : arc90.components;
So, there we have it; a function to create JavaScript namespaces. Enjoy.
Trackback Pings (TrackBack URL for this entry)
http://www.arc90.com/cgi-bin/mt4/mt-tb.cgi/155.
Comments
// Let's try that "for" again.
function createNamespace(ns)
{
// First split the namespace string separating each level of the namespace object.
var splitNs = ns.split(".");
// Define a string, which will hold the name of the object we are currently working with. Initialize to the first part.
var builtNs = splitNs[0];
var i, base = window;
for (i = 0; i < splitNs.length; i++)
{
if (typeof(base[ splitNs[i] ]) == "undefined") base[ splitNs[i] ] = {};
base = base[ splitNs[i] ];
}
return base; // Return the namespace as an object.
}
Posted on July 2, 2008 10:43 PM by Josh W
I got something and something not.
you give only 50% guidance. if you put one example with every blog.
Posted on August 7, 2008 12:56 PM by Mazharkhan
Thanks for the comments. To Mazharkhan, I actually do have an example of how to use the function, but I realize that I sort of buried it in the middle. Basically, you use the function as such:
createNamespace("arc90.components");
This creates the namespace, so now you can define functions and classes such as:
arc90.components.CheckBox = {};
The advantage of using the function is that if you don't, you will have to define each level of the namespace separately, like this:
var arc90 = {};
var arc90.components = {};
In addition, you would have to check to see if those objects already exist. Otherwise you will overwrite them with blank objects, which is not what you want to do when defining a namespace.
As for the first comment, I promise to address it soon.
Posted on August 7, 2008 1:11 PM by Alex Melman
Dreaming the Right Dreams | Main | Getting started with PDO_MSSQL

You have a typo:
for (i = 0, i instead of
for (i = 0; i ~~~ gotta love those semicolons!
Also "splitNs" was only partially renamed to "splitType"
function createNamespace(ns)
{
// First split the namespace string separating each level of the namespace object.
var splitNs = ns.split(".");
// Define a string, which will hold the name of the object we are currently working with. Initialize to the first part.
var builtNs = splitNs[0];
for (i = 0; i {
// Add the next part of the namespace only if we are at the second level or further.
builtNs += (i > 0) ? ("." + splitNs[i]) : "";
// Check if the object we want to add exists, and add a new empty object if it doesnt.
eval(builtNs + " = typeof(" + builtNs + ") =='undefined' ? {} : " + builtNs + "; ");
}
return eval(ns); // Return the namespace as an object.
}
You also might be able to use "window" instead of "eval", as eval can but unsafe.
function createNamespace(ns)
{
// First split the namespace string separating each level of the namespace object.
var splitNs = ns.split(".");
// Define a string, which will hold the name of the object we are currently working with. Initialize to the first part to the current window.
var i, base = window;
for (i = 0; i {
// if it is undefined, set it to an object.
if (typeof(base[ splitNs[i] ]) == "undefined") base[ splitNs[i] ] = {};
// update pointer to current object
base = base[ splitNs[i] ];
}
return base; // Return the namespace as an object.
}
Posted on July 2, 2008 10:36 PM by Josh W