Dojo, Provide

Before I get into the article, let handle some house-keeping. I apologize for missing the last mid-week article. I have been really busy with the next version of and have been diligently working on porting to YUI. Both projects are progressing nicely, but not as quickly as I had hoped; I will keep you abreast of any progress.

While working with Dojo, I took a look under the hood at its namespacing function, dojo.provide(namespace). The function registers the namespace on a protected object attached to the namespacing function itself, if it does not already exist. Then it returns an object at the desired namespace (this object is also a function). The protected object allows for quick detection to see if a given namespace exists, while not polluting the global context with an extra variable. Here are two simple functions that work in much the same way:

Example 1: provide()

var mesnider_provide = function(s) {
    var list = ( + s).split(/\./),
        sb = [],
        context = window;

    if (! mesnider_provide._provided) {mesnider_provide._provided = {};}

    for (var i = 0; i < list.length; i += 1) {
        var name = list[i];
        if (! context[name]) {
            sb[i] = name;
            context[name] = function() {};
            mesnider_provide._provided[sb.join(.)] = context[name];

        context = context[name];

    return context;

Example 2: is_provided()

var mesnider_is_provided = function(s) {
    return mesnider_provide._provided[ + s];

The provide function in Example 1, splits the argument string (s) around all periods (.). This creates a list that can be traversed for namespace creation. The _provided object is added to the function itself, if it does not already exist, to be used for fast namespace detection with the is_provided function of Example 2. All namespaces are function objects (unless already defined by unrelated code) attached, starting from the global context (window), then moving down. The sb array is used as a string buffer when adding to the _provided object, so that the whole namespace up to that point can be added. Lastly, the context is adjusted for the next iteration so it can be returned at the end of the provided function (this will be the newly created object, or the namespace previously created).

Example 3: Using provide()

var myNamespace = mesnider_provide(;
// mesnider_provide._provide will have the following added
//	mesnider_provide._provide[mesnider]
//	mesnider_provide._provide[]
//	mesnider_provide._provide[]

// and the following is true and important.
// 	if you know the namespace exists, this is faster than using provide
myNamespace == mesnider_is_provided(;

The is_provided function needs only to check if the provided namespace exists in the provide._provided object. Keep in mind that it does not return a boolean, but instead a truthy value of the namespace object, or undefined when the namespace does not exist. The function was coded this way, because there are times that a developer has the namespace string and desires to have the namespace object. Normally they would need to use the provide method to convert the string into the namespace object, but the is_provided function prevents the need for that conversion, improving code performance.