I can get close enough to solving my problem by using an approach similar to JQuery's ready()
function. However, it does rely on defining the root namespace before anything else. The root namespace also includes functionality which allows callbacks to be registered.
var Namespace = (function () {
var namespace = {};
namespace.ReadyCallbacks = [];
namespace.Ready = function (callback, queueJump) {
if (queueJump)
namespace.ReadyCallbacks.unshift(callback);
else
namespace.ReadyCallbacks.push(callback);
};
namespace.Begin = function () {
for (x = 0; x < namespace.ReadyCallbacks.length; x++) {
namespace.ReadyCallbacks[x]();
}
};
return namespace;
})();
Importantly this distinguishes between callbacks which should run before others. This allows framework modules to define sub-namespaces and functions before user scripts are executed. (Even if user scripts are loaded first).
User Scripts
Namespace.Ready(function () {
console.log(Namespace.SubSpace.Func()); // prints "Module 1"
});
Framework Module
Namespace.Ready(function () {
Namespace.SubSpace = (function () {
var subspace = {};
subspace.Func = function () {
return "Module 1";
};
return subspace;
})();
}, true);
Finally, calling Namespace.Begin()
executes everything in the correct order. Also, since I'm using JQuery anyway, I can wrap this in $(document).ready()
.
I'm not terribly proficient in javascript so I'm not sure how 'correct' this approach is, I'd welcome comments & suggestions.