Solution one

Here’s the code we’re studying.

var AAA = (function (BBB)
{
    BBB.fff = function(ccc)
    {
        return {
            ggg: function(ddd)
            {
                return BBB.hhh(ddd, ccc.iii());
            }
        };
    };
    return BBB;

}(AAA || {}));

Verbal summary

We are making sure that there’s an object AAA and giving it an attribute AAA.fff, which is a function. We won’t say more about the function in this summary.

Hoisting once-only arguments

First, we’ll hoist the argument to the anonymous function into its body. We can always do this, without changing the meaning, provided the function is called only once.

var AAA = function ()
{
    var BBB = AAA || {};
    BBB.fff = function(ccc)
    {
        return {
            ggg: function(ddd)
            {
                return BBB.hhh(ddd, ccc.iii());
            }
        };
    };
    return BBB;

}();

There, that’s better. We no longer have to read to the end of the function to find out what BBB is (and in particular its relationship with AAA).

What is AAA?

Next, we’ll hide (or ignore) the assigment to BBB.fff. This assignment sets an attribute on the object pointed to by the variable BBB. In other words, it mutates the object pointed to by BBB, but the variable BBB still points to the same object as it did before.

var AAA = function ()
{
    var BBB = AAA || {};
    return BBB;
}();

If AAA starts out as an object then the expression

AAA || {}

evaluates to AAA, while if AAA is undefined then it evaluates to the newly created object literal (the left-and-right curly braces). In either case, this value is assigned to the local variable BBB, which is then returned by the anonymous function and bound to AAA.

Put another way, if AAA starts off as undefined then it is bound to a new object, while if it starts off as an object then it finishes as the same object.

Therefore, our truncated version of the original exercise is equivalent to

var AAA = AAA || {};

This idiom is very common in JavaScript, and is (as here) a consequence of using objects as namespaces (which is better than using the global object) and defensiveness about the order in which files are loaded.

Here’s a command line session that shows this equivalence. To begin with AAA is undefined and the assignment binds AAA to a new object. For the second assignment AAA is defined and the assignment binds AAA to the object is already bound to.

js> var AAA = AAA || {}
js> AAA
[object Object]
js> pointer = AAA
[object Object]
js> var AAA = AAA || {}
js> pointer === AAA
true

The assignment to BBB.fff

Reading the code, it looks as if BBB is local to the anonymous function. As a variable it is, but its value is not. The value of BBB is bound to the global object AAA at the end of the function call.

The following is almost equivalent to our original JavaScript code. Note that BBB.hhh has been changed to AAA.hhh.

var AAA = AAA || {};

AAA.fff = function(ccc)
{
    return {
        ggg: function(ddd)
        {
            return AAA.hhh(ddd, ccc.iii());
        }
    };
};

Caveat

Why did I say almost equivalent? Because we might subsequently do something like

var CCC = AAA;
AAA = undefined;

For the original code the closure variable BBB still exists and points to the same object as CCC, even though AAA is undefined. Thus, the reference to BBB.hhh in the original code will continue to work.

For the revised code, when the value of AAA is set to undefined the reference to AAA.hhh will fail.