Writing Modular JavaScript!

Of all the ways in which you can write JavaScript, modular style is one of the most intriguing. It allows you to make your data and methods private. It does it by using closures. Module pattern thrives on the fact that your App can be made more manageable by dividing it into modules. And successfully, hiding, abstracting the detailed parts under those modules, while leaving simple interfaces open to carry out the tasks!

In JavaScript per se, everything is global. So if you’re used to write your code in functions, you would realize that everything you write is global, and can easily be encroached upon by some other code in other files. What if you depended on a global variable’s value, only to have it changed by some other non-suspecting JavaScript code. As a best practice we should always keep our global footprint down to a minimum.

Let’s see module design pattern in action!

var MyModule = (function(){
    var privateVariable;
    var privateMethod = function() {
    };
    return {
        publicMethod: function(){
            //can call private method here
            privateMethod();
        }
   };
}());

That is the simplest module. Anything which is inside return block, is accessible from outside. If you type the above code in console, we’ll see that the privateVariable, and privateMethod isn’t available to us under the global variable MyModule only publicMethod is available. MyModule Building on the same concept we’ll now make another app that is more like a real world app which uses jQuery too. Let’s make an AppleApp.

This app will have a private variable apples which we’ll be decrementing and incrementing by two private methods eatApple() and buyApples(). We will also define another method called viewApples(), this will return us the private variable apples!

We’ll bind methods to buttons like we normally do in a real web application, and this we’ll do in a private method called bindDOMEvents().

var AppleApp = (function ($) {
    //private variables and methods
    var apples = 0;
	var eatApple = function () {
        if (apples > 0) {
            apples--;
        } else {
            alert("Cannot eat. No stock. Buy first.");
        }
		$(document).trigger("ateApple.appleApp");
    };
	var buyApples = function (newApples) {
        apples += parseInt(newApples, 10);
		$(document).trigger("addedApples.appleApp");
    };
	var bindDOMEvents = function() {
		//on button clicks
		$('input#eatApple').on("click", function(){
			eatApple();
		});
		$('input#buyApples').on("click";, function(){
			var num = $('#numberOfApples').val();
			buyApples(num);
		});
		//to display current value of apples
		$(document).on("addedApples.appleApp ateApple.appleApp", function(){
			$('span.box').text(apples);
		});
		//to change the label of button
		$('#numberOfApples').on("change", function(){
			$('input#buyApples').attr('value', 'buyApples('+$(this).val()+')');
		});
		
	};
	
	//our own document.ready function
	(function(){
		$('span.box').text(apples);
		$('input#buyApples').attr('value', 'buyApples('+$('#numberOfApples').val()+')');
		bindDOMEvents();
	}());
    
	//public methods
	return {
		viewApples: function() {
			return apples;
		}
    };
}(jQuery));

There’s a lot going on with the code above. Firstly, we pass jQuery object to our module’s anonymous function as an argument, so that we can access it locally without any conflicts. Then we define apples, eatApple(), buyApples(), bindDOMEvents().

Then we create another self-invoking function closure which executes immediately and we called the above defined bindDOMEvents(). This works because we include our script just before the ending of the body tag, and by then the whole DOM structure is made ready by the browser. Else we would have to use jQuery’s document.ready method.

//our own document.ready function
	(function(){
		$('span.box').text(apples);
		$('input#buyApples').attr('value', 'buyApples('+$('#numberOfApples').val()+')');
		bindDOMEvents();
	}());

And after that we finally have the return block, which contains a public method. It’s the only method which can be called from outside, via AppleApp.viewApples(). I’ve even highlighted the relevant parts!

You can access, copy, edit, and run the code from the following jsfiddle link.

http://jsfiddle.net/ankeetmaini/Ang8x/

And this is the AppleApp in fullscreen!

http://jsfiddle.net/ankeetmaini/Ang8x/embedded/result/

6 thoughts on “Writing Modular JavaScript!”

  1. Wonderful article on modular JS! Thanks, Ankeet. When we mention that ” This works because we include our script just before the ending of the body tag, and by then the whole DOM structure is made ready by the browser, ” I guess the body tag comes into play only if the script is written directly into jsp as a part of it. If it is a js file included by tag I guess the .trigger and .on would automatically take care of it as in dojo pub and sub.

    Like

    1. Thank you sir! If we write the script tag just before the body ends even if it is an external js file the browser will start parsing the html from the top and by the time it reaches the script tag it would have created all the DOM elements written in the body. But we are used to include our JavaScript files in the head tag which causes the loading of JavaScript files first and then creation of Dom structure and in that case to avoid the risk of our JavaScript functions executing before the dom is ready we need to depend on jQuery’s document.ready utility!

      Sent from my Windows Phone

      Like

Leave a comment