Thursday, September 24, 2015

Module Pattern in Javascript

In today's post, I will be discussing the basic Module pattern in JavaScript. It is a well known coding pattern in JavaScript and if you have written some front-end code, you might already be familiar with this.

Module Pattern

As we know we do not have access modifiers (e.g. private, public) in JavaScript. In other languages, we can have our private and public variables to control the visibility and hide the implementation details. In JavaScript, we can use the module pattern to emulate the concept of classes. By using this, we can return the specific parts which we want to expose and hide the particular parts from global scope. Let's move along with an example to understand the Module pattern:

Suppose, we have an object literal like this:

var dom = {

    _counter : 0,

    generateId: function(){

        return 'custom' + this._counter++;

    },

    create: function(tagName){

        var el = document.createElement(tagName); 

        el.Id = this.generateId();

        return el;

    }

}


As you can see we have two methods exposed: create() and generateId(). The expected usage of this is to create new objects using create() method. Inside the create method, we create a new element,  assign an id to the element and return it.

So we simply create two buttons like this:

var el1 = dom.create('button');

var el2 = dom.create('button');

document.writeln(el1.Id);

document.writeln(el2.Id);


And if we look at the outputs, we will see custom0 and custom1. So that's good for our purpose and should suffice.

However, as you can see, we have exposed the counter and generateId methods as well which were not needed to be exposed. This can be bad. For example, setting the counter variable to some bad value might interfere with the normal execution of the program.

For example, if we set

dom._counter = 'abcd'

var el1 = dom.create('button');

var el2 = dom.create('button');

document.writeln(el1.Id);

document.writeln(el2.Id);

the output will be customNan and customNan.  So the ids are not unique anymore.


The way we would have handled this in C# or Java is by making the counter variable private and not exposing any setter and just use it internally. But as I mentioned earlier, we don't have access modifiers in JavaScript.

The way we can handle this is by creating a module in JavaScript. The basic module pattern involves an immediately invoked function and whatever we return will be publicly accessible outside the function.


var dom = (function(){

    var counter = 0;

    function generateId(){

        return 'custom' + counter++;

    }

    return{

        create: function(tagName){

            var el = document.createElement(tagName); 

            el.Id = generateId();

            return el;

        }       

    }  

}());


If you look at the last line closely, the function is immediately called. If you look at the return statement, we only return one function called create(). Nothing else is exposed from this module.
So now if you create elements like this:

var el1 = dom.create('button');

var el2 = dom.create('button');

document.writeln(el1.Id);

document.writeln(el2.Id);

You will get custom0 and custom1 as the output. The counter variable is now shielded from the global scope, so it acts just like a private variable. It exists only inside the module's closure. So except generateId() and create() no one else can access the counter variable.

Another thing that you can do to make it look cleaner is write create() function before the return statement and return the pointer for the create() function that we created:

var dom = (function(){

    var counter = 0;

    function generateId(){

        return 'custom' + counter++;

    }

    function create(tagName){

        var el = document.createElement(tagName); 

        el.Id = generateId();

        return el;

    }

    return{

        create: create

    }

}());

This further allows us to use the create function anywhere inside the module, if needed and not just the return object.

Conclusion

The Module pattern is a very powerful pattern and helps us to write cleaner code. We can make our variables or functions private and have more control on what we are exposing to the outside world. This pattern has a lot of variations and is quite evolved and I will try to cover the other variations in future posts.

For future updates to my weekly blog, please subscribe to my blog via the "Subscribe To Weekly Post" feature at the right and follow me on Twitter. Until then Happy Coding :)


2 comments:

  1. I know this post id from a year ago but for some reasons I found this to be much easier to understand than Modules in "Javascript: the Good Parts". So thank you, really enjoying your js posts!

    ReplyDelete
  2. Hi,
    I am glad you liked the post.
    Thanks for the feedback and comment :)

    Thanks,
    Abhi

    ReplyDelete