JavaScript Module Pattern explained

Here I am going to explain in detail about JavaScript Module pattern which is one of the most significant patterns in JavaScript.
The Module pattern allows developers to organize their applications in modules or functional areas. Most languages allow programs to be organized in logical or functional units called packages, modules, or areas. JavaScript has no special syntax to do so, but the Module pattern is a frequently used technique to organize parts of the program as self-contained units that can be changed independently without affecting any other module.
The Module pattern makes use of immediate anonymous functions and closures. Here is the idea in code:

var module = (function () {
     // private area ...
    return {
    // public area ...
    };
}());

In its most basic form, the Module is an immediate function whose return value is assigned to a variable (called module in our example).

In the private area of the module you define variables and functions which represent the module’s private state. It is off-limits to the outside world. This is courtesy of the closure created by the function in which the private state is maintained.

The public area is the returned object literal. It represents the public interface (properties and methods) of the module which is accessible from anywhere in the program.

Let’s look at a simple example:

var module = (function () {
    // private area

    var count = 0;
    var increment = function () { count++; };
    var decrement = function () { count--; };

    return {

        // public area

        addOne: function () { increment(); },
        subtractOne: function () { decrement(); },
        getCount: function () { return count; }
    };
})();

Again, the private area is inaccessible from outside the module. Through closure, the public area does have access to all private members. For example, the variable count cannot be changed directly, but consumers of the module can indirectly change the value through the addOne and subtractOne methods on the public interface.

Notice also how a new object is created without the new operator by defining an object literal which is returned by the anonymous function.

A variety of the Module pattern is called the Revealing Module pattern. Its purpose is to reveal private variables and/or functions via the public interface. Here is an example:

var module = (function () {

    // private area

    var count = 0;
    var increment = function () {count++;};
    var decrement = function () {count--;};

    return {

        // public area

        add: function () { increment(); },
        subtract: function () { decrement(); },
        getCount: function () { return count; },

        inc: increment,                // revealing method
        dec: decrement                 // revealing method
    };
})();

Two new methods were added to the public interface: inc and dec. They ‘reveal’ the private functions increment and decrement to outside consumers of the module.

Here is a slightly modified way to implement the revealing module pattern. First, create all properties and methods as private local variables and functions and, next, only return the ones that should be publicly available. You can use the same or different names for the public members. Here is an example where we use the same names:

var module = (function () {

    var count = 0;
    var increment = function () { count++; };
    var decrement = function () { count--; };

    return {
        increment: increment,       // same names
        decrement: decrement    
    };
})();

In this last example the returned object literal’s purpose has been reduced to a mechanism to expose private members as public members. There is no need to have any code in the return value. This is an elegant and tidy way of structuring your immediate functions modules.

There is nothing to prevent you from creating global variables or interact with existing global objects from within the module. However, if you start doing this is becomes difficult to keep track of what is inside and what is outside. Wouldn’t it be clearer if we could import the necessary globals into the module and only touch these? The answer is yes and, in fact, this is common best practice. You import global variables as arguments into the module functions, like so:

var module = (function (win, $, undefined) {

    var doc = win.document;
    var nav = win.navigation;    

    return {

    };

})(window, jQuery);

In this example we are importing 2 global arguments at the bottom of the code: they are window (the global object) and jQuery. Notice that we are also adding a third parameter named undefined at the top which seems odd. Let’s examine each of these arguments.

The first argument named window imports the global object into the module. A couple of properties on the window are assigned to local variables for direct and fast access: they are document and navigation. Following these assignments there is no need to directly access the global object anymore (win or window) and it will be obvious if we do. Also, assigning global properties to local variables will speed up the application as it reduces the need for the JavaScript engine to follow the scope chain to resolve the references.

The second argument jQuery is represented by the $ parameter. As mentioned earlier, there are other libraries that use the same $ global variable name (for example, Prototype) which can cause name conflicts on your page. By including jQuery as an argument and binding it to the parameter named $, then, in your module, you can be sure that $ is in fact an alias for jQuery and nothing else.

The third argument is a variable named undefined. It is included to prevent hackers from overwriting the built-in undefined JavaScript variable (which has a value of undefined by default). Here is how that would work.

As you saw, only two arguments are provided at the end of the module (when invoking the immediate function), whereas the anonymous function accepts three parameters. JavaScript will not complain when too many or too few arguments are provided when calling a function. Any extra arguments will be ignored and any missing arguments will be undefined. In our module we have a missing argument whose name and value will be undefined. So, if someone decided that it would be funny to reassign undefined = true, then this will correct that situation and have no adverse effect on your module; we know that undefined is truly undefined.

The above Module pattern is widely used and is sufficient for most situations. However, when the project starts to grow even larger, you may feel the need to split your module into multiple files. However, you have to be careful because if your JavaScript files are not included in the right order, you run the risk of overwriting all or parts of your own module. This can be solved with the Partial Module pattern. Below is some simple code that shows the idea:

var module = (function (self) {

    var top = 10;

    self.multiply = function (x,y) { return x * y; };
    self.divide = function (x,y) { return x / y; };
    self.getTop = function () { return top; };

    return self;
    
})(module || {});

Notice how module is passed as an argument at the bottom of the module. If no module exists then an empty object will be passed in. Inside the module the self reference (that is, the module itself) is enhanced with three methods: multiply, divide, and getTop. The function returnsself which is then (re-) assigned to a variable called module.

A disadvantage of the Partial module is that each file has its own private state which is not shared with the other Partial modules. For example, the top variable in the above code is only visible in this file but not in other files that define the module.

This can be solved by assigning the incoming state to the local state and enhance it with additional properties and methods. Once a module is fully loaded, that is all files are loaded, we remove the public state from the module. If it is not fully loaded, we assign the local state to the self.state which is then carried to the next file. If this sounds complicated, it is, but here is an example of the so-called private state module:

var module = (function (self) {

    var state = self.state = self.state || {};
    
    // private state enhancements
    state.index = 9;
    state.getIndex = function () {return this.index;};

    if (isLoaded()) {
        delete self.state;
    } else {
        self.state = state;
    }

    // addional code

    return self;
    
})(module || {});

We do not recommend this last pattern. The added complexity of reassigning the internal state in each file and the overhead of determining whether all module files have been loaded is too high a price for being able to share private variables.

In reality the limitation of not sharing private state may not be always be bad; it forces you to build self-contained sub-modules each of which has its own responsibility as part of the bigger module.

The Namespace pattern is frequently used in combination with Module pattern. A common approach is as follows: at the beginning of each file a namespace is defined which is then followed by a module that is added to this namespace. Here is an outline of this approach:

Click here to learn about Namespace Pattern
var events = MyApplication.namespace("Utils.Events");

events.module = (function () {
    // private area ...
    return {
        // public area ...
    };
})();

Because the namespace method returns a reference to itself, you can shorten the code a bit by immediately assigning the module to the namespace. An additional benefit is that it also removes the need for a global variable (named events in the example above).

MyApplication.namespace("Util.Events").module = (function () {

    // private area ...

    return {

        // public area ...

    };
})();

This way of chaining code together is another frequently used pattern, called the Chaining pattern which we will discuss in the next section.

Before wrapping up, here are some notable points about the Module pattern. The Module pattern is JavaScript’s manifestation of the Gang-of-Four Singleton pattern. Modules are immediate functions that execute only once, their return value being the module. Only a single instance of the module will ever exist (which is the idea behind Singleton).As mentioned before, the Module pattern is widely used. You can confirm this by opening up any popular JavaScript library such as jQuery, ExtJs, Backbone, YUI, Ember, Node.js and you’ll recognize this pattern right away. Some libraries, such as jQuery and Backbone have their entire code base in a single module. Others, such as ExtJs and YUI are partitioned in namespaces and include numerous modules.

Another reason why Module is so popular in the JavaScript community is because it exhibits many characteristics of good object-oriented design, including: information hiding, encapsulation, high cohesion/loose coupling, open/closed design and extensibility.

local_offerevent_note April 17, 2015

account_box srinivasaraju nadimpalli


local_offer