Skip to content


JavaScript Namespaces

Note: The code in this posting has been strongly influenced by the Yahoo UI Library (an EXCELLENT library). I’ve made some modifications, but in many cases my code was functionally equivalent (if not identical) to the code in the library.

“Who” Should Do This

Everyone writing JavaScript.

“What” Is This

Creating a single global JavaScript object that will contain all of your JavaScript.

“Where” Should This Live

The primary namespace should be in its own script file.

“When” Should I Do This

Any time you write JavaScript.

“Why” Should I Do This

Avoid conflicts with other scripts.
Create code that is more manageable and portable.
Better memory management via scoped objects.

“How” Should I Do This

First, choose a name that represents your root/base namespace. It should be short in length, but unique enough that it won’t conflict with other global variables. Your name (or organization name), abbreviation of the name, or an acronym is a good place to start.

For example, if your organization was “ACME, Inc.”, you might use “ACME” as your namespace name. If you are an individual developer, you might choose your initials. For my examples, I’m going to use “FOTI” as the namespace name. Note, I’m using all UPPERCASE letters to define my namespace. This convention seems to be the norm, and I like it because I think there is less chance for global conflicts this way (it also makes more sense for those who use initials).

To create the namespace, lets start with the following in a file of its own (obviously, replace all instances of FOTI with your own namespace):
foti.js

if ((typeof FOTI == "undefined") || (null == FOTI)) {
    /**
     * The FOTI object is the global (namespace) object used by the FOTI
     * JavaScript Library.  All FOTI objects reside within this object scope.
     */
    var FOTI = {};
}

This checks to see if a global FOTI object already exists, and creates a new empty object if it does not. This is the base from which all of our work will reside. Note that I’ve chosen the method of checking if the variable FOTI is undefined (meaning declared but not assigned, or simply not declared) or null (meaning it has been declared and assigned, but now contains a null value). Essentially, I’m checking to make sure that I have a valid object that I can add methods and properties to.

Next we’ll want to add the ability to create additional inner namespaces. For example, I may want the following namespaces:
FOTI.util
FOTI.page
FOTI.widget
FOTI.widget.controls

In order to facilitate this, I’m going to add a method to our global object for creating nested namespaces. This is based off of the Yahoo UI Library‘s YAHOO object, but I’ve taken a slightly different approach. My method will take a single argument, which is a string or an array of strings (allowing for multiple namespaces to be created at the same time). Here’s that method:

/**
 * Create the specified namespace(s)
 * @static
 * @param  {String | Array} s Namespaces to create 
 * @return {Object}  A reference to the last 
 * namespace object created or an empty global 
 * object if the namespace couldn't be created
 */
FOTI.namespace = function(s) {
    var a, o, i, j, d;
    // Determine if s is string or array and
    // force it to an array
    if (typeof s === 'string') {
        a = [s];
    }
    else if (s.length !== undefined) {
        a = s;
    }
    else {
        // Neither a string or an array was passed in, so exit
        return {};
    }
    for (i = 0; i < a.length; i++) {
        d = a[i].split(".");        
        o = FOTI;
        // FOTI is implied, so it is ignored if it is included
        for (j = (d[0] == "FOTI") ? 1 : 0; j < d.length; j++) {
            o[d[j]] = o[d[j]] || {};
            o = o[d[j]];
        }
    }
    return o;    
};

Now we’ve got a nice way to setup multiple namespaces contained within our global FOTI namespace. So I’m going to add a self-invoking anonymous function that will create some default namespaces:

(function() {
    FOTI.namespace(["util", "page", "widget.control"]);
})();

Great! Now, how can we put this to use?
One use for this is to contain the scripts for our individual pages within our global object. This will help prevent conflicts with other scripts. So lets start by creating an empty HTML page. This is going to be our “home” page:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset:utf-8">
  <title>Home</title>
  <script type="text/javascript" src="http://yui.yahooapis.com/2.3.1/build/yahoo-dom-event/yahoo-dom-event.js"></script>
  <script type="text/javascript" src="/inc/js/foti/foti.js"></script>
  <script type="text/javascript" src="/inc/js/foti/page/home.js"></script>
</head>
<body>
<div id="container">
</div>
</body>
</html>

You’ll note that I’ve included the Yahoo UI Library‘s yahoo-dom-event script. That’s because the exceptional DOM and Event handling Utilities give me a lot of bang for my buck. I’m going to use the Yahoo Event Utility extensively.

Next, lets create the stub for our home page’s main script. This is going to be a singleton (only 1 instance of this script will ever be needed) so you’ll note that I’m assigning the result of a self-invoking function to the FOTI.page.home property. I use the YUI Event Utility to call the init method when the page has loaded, and I’m giving FOTI.page.home the scope for ‘this’:

FOTI.page.home = function() {
    return {
        init : function() {
            alert(this.greeting);
        },
        greeting : "Welcome!"
    };
}();
YAHOO.util.Event.on(window, 'load', FOTI.page.home.init, FOTI.page.home, true);

There you have it. We’ve created our Global namespace object (FOTI), we added a sub-namespace object (page) which has a property (home) that contains an instance of an object for our current page’s scripts (this object has the properties init and greeting). We can add all of our page-specific scripts to this object and we’ve avoided conflicts with all other global objects by containing them in our nice and neat namespaces.

Well, that’s all for now. I could probably continue to elaborate, clean up, and expand this example. But this post is getting pretty long as it is. Enjoy. 🙂

Posted in General, Web Development.


3 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Steve says

    Flex all the way 😉

  2. Dabrowski The Great says

    > add a self-invoking anonymous function that will create some default namespaces

    You mean, a bit of code?

    How does this:
    (function() {
    FOTI.namespace([“util”, “page”, “widget.control”]);
    })();

    Differ from:
    FOTI.namespace([“util”, “page”, “widget.control”]);

    ???

  3. Peter Foti says

    Hmmm… to be honest, I don’t know why I did it that way. Perhaps I was simply trying to demonstrate writing a self-invoking anonymous function? But in this case, I can’t see a real need for it. So omitting the anonymous function would be fine.



Some HTML is OK

or, reply to this post via trackback.