JavaScript: Using Functions in a Namespace

Global is Bad. Namespaces provide a way to limit the use of the global space and avoid potential collisions with other code.

Dr. Jane Xenos wrote a small manual explaining some osteopathic techniques you can do at home.

Order Manual Therapy: A Self-help Guide to Osteopathic Treatment from Amazon.com.

Introduction

When you learn to program using JavaScript, most methods put all variables and functions into the global namespace. This makes it easier to understand how JS works and you can start writing programs right away.

Using global variables and functions works fine. That is, up until you start working other people—such as using a library—or start trying to reuse code. Then you have to worry about multiple variables or functions that have the same name colliding. The solution is to use namespaces. The goal is to put all the code in a single namespace (global variable) object, and having everything else a property or method of that object.

Many JS gurus have talked about namespaces. Flanagan's JavaScript: The Definitive Guide has it. Douglas Crockford calls it the Module Pattern, although I can't really find it anywhere; it might be in his book JavaScript: The Good Parts.

There are lots of variations on ways to use a namespace that work fairly well, but most have drawbacks. Even well accepted methods can cause severe limitations on future reuse and expansion. This article progresses from the most basic method and progresses to a form used in many places, and is common in jQuery.

Use The Example Code

Namespace techniques are not used well in the code that executes on this page. The methods I'm demonstrating conflict with each other, but they have to be used to show how they work. So generally, the actual code that runs (as opposed to the examples) on this page is not something you want to cut and paste. Having said that, all of the code is still in a single namespace.

The code here is also lazy and uses onclick=whatever(this) instead of DOM events. It's an easy cut and paste way to transfer the proper context of this, and it makes the calling code easier to follow. I started this just as a reminder to myself, not really planning to post it online, so the lazy way will stay.

var and or

There are a couple of useful details about the keyword var and the operator || that I was unaware of for quite a while.

It is legal to use the var keyword on a variable that has already been declared. The var statement is ignored.

The "logical (||) or" does not return a Boolean unless its operands are Boolean. It evaluates the first operand (the expression on the left) and if it evaluates to a value that can be converted to true, it returns the unconverted expression. If not, it returns the value of the expression on the right.

Putting these together makes it very easy to create a namespace without disturbing an existing one.

var com = com || {};
com.YourFriendPaul = com.YourFriendPaul || {};

The code creates a com object if one doesn't exist, and then adds a YourFriendPaul object if it doesn't exist. As suggested by Flanagan, I use the name of my website as my namespace to make it unlikely that there will be any name conflicts

The Ways to Code It

All of the code shown here is in a single global variable named mySpace. When a button is clicked, a function is executed by using the name of the function, for example mySpace.myObj1();.

Where We Start

A simple first step is to assign the return value of the function to a new element of the object:

mySpace.myObj1 = function() { alert( "this is myObj1" ); };

That works fine for a simple case. But what if you want to add more functionality to myObj1? For instance, if mySpace.util or mySpace.widget were defined this way, then to add any more functionality the original object needs to be modified. That risks breaking something in the working code.

Add Another Method

Now that an object is defined, we can add another method to it.

mySpace.myObj2 = function() { alert( "this is myObj2" ); };
mySpace.myObj2.addSomething = function() { alert( "this is myObj2.addSomething" ); };

Once again it works, but now the methods are called differently depending on if it's the original one or the added one. On the added methods, myObj2 must go before every method call, but the first one is just a call to myObj2. It's fine when you're writing the code and thinking about it, but it can be confusing later if you need to go back and figure out what was done. On the plus side, the object was extended without modifying it but not in a way that will be easy to use.

First, Make an Object

New methods can be attached to an object if we define it first.

mySpace.myObj3 = {};
mySpace.myObj3.first = function() { alert( "this is myObj3.first" ); };
mySpace.myObj3.addSomething = function() { alert( "this is myObj3.addSomething" ); };

This solves the previous problem because all of the methods of myObj3 are called the same way.

But really, we're just back at the first way of doing things, but with an extra object in between that the methods are getting attached to.

Make an Object, Second

There's another way of doing this same thing, but an object is returned instead of creating the object first. This is often called the Module Pattern. (If you read the whole article, look for a comment "by Caridy Patiño - June 14, 2007"; it adds the return value and says why to do it instead of returning creating the object in the return statement.)

mySpace.myObj4 = function(){
    var publics = {};
    publics.first = function() { alert( "this is myObj4.first" ); };
    publics.addSomething = function() { alert( "this is myObj4.addSomething" ); };
    return publics;
}();

Not only is this cleaner, but now the entire myObj4 object can have private variables and function. The only things visible to the rest of the code are things returned in the publics object. Don't forget to execute the function; that's what the last set of parenthesis is for.

This is much cleaner, but now we're back to the problem of needing to change the base function if we want to add something. That's the main reason I use it only for something simple that I know won't be reusing or adding to.

Go Anonymous and Get Closure

There's another minor difficulty with myObj4: portability. As it's written, it could just be assigned to a different variable, such as yourSpace instead of mySpace. And that's fine as long as things don't get complicated. Without going into why that situation can happen, lets just solve it.

mySpace.myObj5 = {};
(function( $ ){

    $.first = function() { alert( "this is myObj5.first" ); };
    $.addSomething = function() { alert( "this is myObj5.addSomething" ); };
})( mySpace.myObj5 );

In this case, the name of the object where the public methods should reside is passed into the function. To move it to a different object only the object passed in as a parameter needs to change.

Look how much easier this is to move to another place than the myObj4 version if you want to access something outside of the function. In myObj4, you would have to change some items that would be hard coded, but in this case the base is passed in, so nothing should need to change.

There's another advantage: more functions can be added without changing the original function.

(function( $ ){

    $.second = function() { alert( "this is myObj5.second" ); };
    $.addMore = function() { alert( "this is myObj5.addMore" ); };
})( mySpace.myObj5 );

There's a little more that can be done with this implementation: other objects or data can be added that are still private, but don't get carried with every function.

(function( $ ){

    $.third = function() {
        alert( "this is myObj5.third\nOn " + $.third.defaults.day + " the color is " + $.third.defaults.color );
    };
    $.third.defaults = { color: "red", day: "Monday" }
})( mySpace.myObj5 );

Conclusion

The examples based on myObj5 may look familiar: they are basically the design pattern for making a jQuery plug-in. Knowing that, there are a lot of resources out there to learn what else can be done with this pattern.

Home Page for YourFriendPaul