Code in JavaScript the smart, modular way

Are you a JavaScript hack or a real developer? Use this quick start guide to learn to write modularized JavaScript code

As I enjoy my extended hiatus (actually, I'm working around the clock on a project) my substitute this week is again Jonathan Freeman, an experienced JavaScript developer at my company, Open Software Integrators. I've heard from many of you who appreciate his clear, valuable JavaScript advice. Here's another installment I hope you will find useful. -- Andrew Oliver

Some people still seem surprised that JavaScript is regarded as a respectable, grown-up programming language for serious applications. In fact, JavaScript development has been maturing nicely for years, with the best practices for modular development as a prime example.

The benefits of writing modular code are well documented: greater maintainability, avoiding monolithic files, and decoupling code into units that can be tested properly. For those of you who'd like to get caught up quickly, here are the common practices employed by modern JavaScript developers to write modularized code.

[ Also by Jonathan Freeman: Your quick guide to better JavaScript testing | JavaScript rules the Web -- but how do you harness its power? Find out in InfoWorld's special report, "The triumph of JavaScript." | Keep up with the latest developer news with InfoWorld's Developer World newsletter. ]

Module pattern

Let's start with a basic design pattern called the module pattern. As you might suspect, this enables us to write code in a modular way, allowing us to protect the execution context of given modules and to expose globally only what we want to expose.The pattern looks something like:

(function(){

//'private' variable

var orderId = 123;

// expose methods and variables by attaching them

// to the global object

window.orderModule = {

getOrderId: function(){

//brought to you by closures

return orderId;

}

};

})()

An anonymous function expression, acting as a factory in this case, is written and called immediately. For speed, you can explicitly pass in variables to the function call, effectively rebinding those variables to a local scope. You'll also see this sometimes as a defensive maneuver in libraries supporting old browsers where certain values (such as undefined) are writeable properties.

(function(global, undefined){

// code here can access the global object quickly,

// and 'undefined' is sure to be 'undefined'

// NOTE: In modern browsers 'undefined' isn't writeable,

// but it's worth keeping it in mind

// when writing code for old browsers.

})(this)

This is just a design pattern. With this technique, to write modular JavaScript, you don't need to include extra libraries. The lack of dependencies is a big plus (or mission critical) in some settings, particularly if you're writing a library. You'll see that most of the popular libraries will use this pattern to encapsulate internal functions and variables, exposing only what's necessary.

If you're writing an application, however, there are a few downsides to this approach. Let's say you create a module that sets a few methods on window.orders. If you want to use those methods in other parts of your application, you need to make sure the module is included before you call them. Then, in the code where you're calling window.orders.getOrderId, you write the code and hope the other script has loaded.

This may not seem like the end of the world, but it can quickly spiral out of control on complicated projects -- and managing script inclusion order gets to be a pain. Also, all of your files have to be synchronously loaded, or you'll invite race conditions in to break your code. If only there was a way to explicitly declare the modules you wanted to use for a given bit of code....

1 2 3 Page
Mobile Security Insider: iOS vs. Android vs. BlackBerry vs. Windows Phone
Join the discussion
Be the first to comment on this article. Our Commenting Policies