Writing maintainable Javascript using modules

When working with Javascript it’s very easy for code to become messy and disorganised without using a design pattern or some kind of structure. This post suggests a number of ways of organising your code using modules. We will use the example of a very basic slideshow (using jQuery) to illustrate the design patterns involved. Here are some jsFiddle demos which contain the source code and a working slideshow:

Structuring code using modules

The idea behind using modules is that when building a website or application you want to keep different bits of functionality separate from each other. This is so one piece of functionality does not interfere with another and changes to one part of the system do not affect another part thereby improving the maintainability of the system. This is known as “separation of concerns” and has an added benefit of making it simpler to test different components of your application.

As we will soon see in Javascript we can use closures and objects to keep variables and methods private to a module. This enables us to write code for a specific component of our application without clashing with other components.

For more information about modular programming there is a Wikipedia article that delves into this subject. Addy Osmani also has a good summary of the module pattern as it pertains to Javascript.

Namespacing

In order to avoid polluting Javascript’s global environment and ensure that our modules do not clash we need to namespace an object where we can attach each of our modules. Each of the design patterns we are looking at will start with the following code:

 var myApp = myApp || {};

 if (myApp.slideShow) {
     console.log('myApp.slideShow is already being used');
 } else {
     myApp.slideShow = // rest of your module here
 }

The first line of Javascript is to ensure we don’t overwrite myApp if it has already been declared somewhere else. If it’s already been declared we just use that existing object otherwise we simply declare a new object.

The if...else statement is to make sure we don’t overwrite myApp’s slideShow property if it already exists.

Addy Osmani has a good post explaining more about namespacing patterns.

Object Literals

The first of our module examples is the object literal method. With this approach we can attach each of our module’s variables and methods as properties to an object literal. For example:

Advantages

This is a very simple way of encapsulating and organising a module. It is also fairly straightforward to unit test your module’s behaviour since all of its properties are exposed.

Disadvantages

Because this approach exposes all of your methods and variables to any other Javascript code this means your module can be easily tampered with. For example, another module could change the init method with myApp.slideShow.init = null which would break the module entirely. With ES5 you could mitigate this problem by using Object.seal which would prevent any of the module’s properties from being changed and stop new properties from being added to the module.

Another downside is that it is cumbersome when trying to refer to the module’s variables and methods. You’ll notice in the code above any time I want to use one of these properties I have to preface it with this.[NAME OF PROPERTY]. In addition, you always have to be careful of the context in which a property is referenced (i.e. what the this value is bound to). Often you will need to store the this value in another variable so that it can still be referred to if a function’s context is different (e.g. the init function above).

Module pattern

In this example rather than using an object literal we simply declare a function which encapsulates the behaviour of our module. We can use closures to refer to private variables and methods and ensure that our module cannot be tampered with. Here is the code:

If we want to expose some of our module’s methods or variables we can use an immediately-invoked function expression (IIFE) instead and then return an object which contains these methods. For example:

Advantages

Unlike object literals this pattern guarantees privacy for all of the functions and variables we want to keep hidden from other modules. This approach also makes it convenient to refer to these variables (we don’t have to worry about the this value).

Disadvantages

Since so much of our module’s behaviour is hidden it can be difficult to unit test.

Revealing module pattern

This approach is very similar to the module pattern except that we reveal a module’s private methods and variables by returning an object which has pointers to them. For example:

You’ll notice in this example we have a newSlidePublic function that calls a private function. We then add this newSlidePublic function to our returned object which reveals the private function when we make a call to myApp.slideShow.newSlide.

Advantages

This pattern has many of the same advantages as the module pattern, however, since we reveal private functions and variables we can more easily unit test the behaviour of this module.

Disadvantages

With this approach we create functions whose sole purpose is to point to private functions which results in some code bloat.

Conclusion

In this post we’ve looked at different approaches for organising and maintaining our jQuery code: object literals, the module pattern and the revealing module pattern. It is quite simple to add some structure to your application using one of these methods and will result in more maintainable and robust code.