/ Engineering

The module pattern in JavaScript

Introduction

If you’re reading this post, I’m assuming you’re interested in JavaScript. It’s the lingua franca of the web and while its simple to start learning JavaScript because of its flexibility, this also makes it an easy language to form bad habits in your code. I’ve been reading Addy Osmani’s online book Learning JavaScript Design Patterns and it’s a great read illustrating the need for design patterns and how they apply to JavaScript specifically.

If I could sum it up, design patterns offer a way to write reusable and effectively structured code that follows best practices — and specifically for JavaScript, this is incredibly important because nowadays, web applications are growing in size and without patterns in place, you’ll see that your well-intentioned app just becomes a plate of spaghetti code!
Spaghetti Code

The purpose of this post is to discuss one particular pattern which I find extremely useful in JavaScript, namely the Module Pattern.

A glance into the module pattern

The idea behind a module in JavaScript is that you want to write code that doesn’t leak into other parts of your codebase — specifically, you want to avoid writing code that’s globally scoped. This is so important because if you’re writing a web application, you’ll soon realize that all the scripts you include are all part of the same global scope, which means that it’s really easy to have variable name clashes!

So what exactly is the module pattern? The idea behind the module pattern is to use a construct that allows you to write private, localized code so that you minimize the amount of code that gets leaked into the global scope.

Let’s take a look at how we would build up to the Module Pattern in JavaScript, starting off with creating an immediately invoked function expression (IIFE) and assigning the result to a variable:

var yourModule = (function () {
  // This is an immediately invoked function expression (IIFE)
  // More JavaScript code in here
})();

The idea here is simple: JavaScript has a global scope, and it creates a new scope every time a function is invoked. This last part is key — it means that every time we invoke a function, JavaScript creates a new scope that contains bindings to all the objects and functions defined within the function that was invoked. The example above is barebones and while you might not see its usefulness yet, you’ll get a better sense with this next example:

var yourModule = (function () {
  var yourPublicFunction = function () {
     return 'Hello World!';
  };
  
  return {
    yourPublicFunction: yourPublicFunction
  };
})();

All we did in the above snippet is fill in our ‘module’ with some JavaScript code, but specifically I want to highlight that our immediately invoked function expression can return a value — and in this case, we’re returning an object literal. What this also means is that we’ll have a reference to the object returned via the yourModule variable and we can execute ‘yourPublicFunction’ as well:

console.log( yourModule.yourPublicFunction() ); // returns 'Hello World!'

This may not be apparent yet, but we can only access the ‘yourPublicFunction’ function object via yourModule — we can’t access or invoke the ‘yourPublicFunction’ function object directly!

console.log( yourPublicFunction() ); // JavaScript error!

Our module is nearly complete — let’s throw in one last wrinkle:

var yourModule = (function () {
  var arrayOfData = [ 'javascript', 'is' ];
  var privateFunction = function (array) {
    return array.concat( 'awesome' );
  };
  var yourPublicFunction = function () {
    var result = privateFunction(arrayOfData);
    return result.join(' ');
  };
  return {
    yourPublicFunction: yourPublicFunction
  };
})();

By including ‘arrayOfData’ and ‘privateFunction,’ I wanted to highlight that the module pattern allows you to define values that can be hidden from your public API. Specifically, your public API is what you decide to expose to people using your module — in this case, users can only access the ‘yourPublicFunction’ function object via your IIFE’s return value. They won’t be able to access ‘arrayOfData’ and ‘privateFunction’ because both these values are closure-scoped to the IIFE. While explaining closures is beyond the scope of this post, take a look at this excellent post.

Conclusion

And that’s all there is to the Module Pattern! The main idea is to encapsulate all function and object definitions within an immediately invoked function expression and then decide what to expose via the IIFE’s return value. Instead of defining all those same functions and objects in the global scope, you’ve now kept them modularized within this pattern and minimized the number of variables declared in the global scope to just your module!