Cutting Loose: Dynamic Namespacing in JavaScript

on in Methods, Events and Scopes
Last modified on

Most of the JavaScript libraries come wrapped in an easy to refer single object. The object acts as a namespace, tightly wrapping everything related to the library and provides a clean systematic handle to access the functionality of the library. For instance, here is a your own awesome library that you just built:

let myAwesomeLibrary = {
    _prop1: '', // private property - should not be accessed externally
    prop2: '' // public property.
};

// Public function of the library
myAwesomeLibrary.fn = function(){};

// Function meant for internal usage. Should not be called from outside.
myAwesomeLibrary._fn2 = function(){};

This is all fine and dandy until you decide that you want to call your new shiny thing myFunkyLibrary instead of myAwesomeLibrary. Suddenly, you find yourself find-and-replacing every occurrence of myAwesomeLibrary.

Next comes a better idea. You understand that myFunkyLibrary is going to change again and again.

var myFunkyLibrary = (function () {
    let _prop1 = ''; // private property - can not be accessed externally
    let _fn2 = function(){}; // function meant for internal usage - this is truly private now

    return {
        prop2: 'some value here', // public property
        fn = function(){} // public function of the library
    };
})();

This looks better. To change the library name, you just make the change at one place. You also get the added benefit of true private properties and functions. Also for namesake, you impress the kids on the block with the “module pattern” term.

Cool! Off you release your new piece of code.

After a few days, you guessed it right. You are not very good at naming things. Some dudes are just not okay proliferating their code with myFunkyLibrary.this and myFunkyLibrary.that.

Name it whatever you feel like but I still think myFunkyLibrary is a pretty awesome name. So you go:

let myFunkyLibrary = function () {
    let _prop1 = ''; // private property - can not be accessed externally
    var _fn2 = function(){}; // function meant for internal usage - this is truly private now

    this.prop2 = 'some value here'; // a public property.
    this.fn = function(){}; // public function of the library
};

With this, you basically allowed any user of your library the freedom to dynamically namespace/use your library with any name he wants, like this:

// their own object literal
let $externalLib_Proto = {};

// aliasing your library to his object
myFunkyLibrary.call($externalLib_Proto);

// calling your library
$externalLib_Proto.fn();

This is what we call dynamic namespacing. We wrapped the entire library and used this as a stand-in for the execution context. The user of the library gets to choose what that context is by invoking the library on an object literal of their choice using call(). Nice and simple!

Related posts