Click here to Skip to main content
15,868,420 members
Articles / Programming Languages / Javascript

JavaScript Design Patterns and IIFE

Rate me:
Please Sign up or sign in to vote.
3.36/5 (10 votes)
20 Sep 2014CPOL5 min read 27.7K   8   6
This article will explain a JavaScript design pattern called the Revealing Module Pattern

Introduction

In this article, I'll be explaining one of the popular design patterns used in JavaScript called "Revealing Module Pattern". As it is a JavaScript design pattern, the only pre-requisite is basic knowledge of JavaScript. Along the way, I'll also explain some basic JavaScript constructs which will help us write JavaScript in an Object Oriented approach. I'll also be explaining another concept called IIFE (Immediately Invoked Function Expression).

Let's Get Started

Here, we are talking about design patterns and obviously Object Oriented Programming comes into the picture when we talk about design patterns. So you must be thinking we have to write a class, create objects, encapsulate/abstract members, etc. But in JavaScript, we can't create a class like we do in other Object Oriented Programming languages C++/C#, etc. However don't worry, we'll see later how to simulate classes in JavaScript. Let's get some JavaScript concepts cleared before we go further into creating classes.

Objects

In JavaScript, everything is an object with the exception of number, string, boolean, null and undefined. JavaScript objects are similar to dictionaries with key/value pairs.

Object Literal Notation

The object literal notation is used to denote objects in JavaScript.

Example: Here, we define an employee object named employeeObj with 3 properties - firstName, lastName and age.

JavaScript
var employeeObj = {
 firstName : "Robert", 
 lastName : "Bosch",
 age : 31
};

We can also create objects by creating an instance of the Object type. We can also start adding properties in the object directly.

JavaScript
var obj = new Object();
obj.firstName = "John"; 
obj.lastName = "Bosch";

Functions and Scope

If we define a variable which is not inside any function, then that variable would be called a global variable. And defining a variable within a function would be local to that function and so the scope of the local variable would be within the function.

In the example below, "a" is a global variable and so it is accessible within the function AddMe and from outside too. "b" again is a local variable to the function AddMe so won't be accessible outside of the function AddMe. This is a very important concept which leads us to another concept called closure which we explain below.

JavaScript
// global variable
var a = 27;    // define a function with a parameter valueToAdd
function AddMe(valueToAdd){
  var b = 100;
  return a + b + valueToAdd;
}
document.writeln(AddMe(50));                                                

Closure

JavaScript allows writing nested functions, i.e., function within a function and so on. And the inner functions can access variables defined outside the inner function and this concept is called a Closure. Closure is a computer programming term and for those interested to know more about it, you can read from the link below:

So in the example below, the addinner function using the variables a and b defined outside it creates a closure so that those variables stay beyond there scope. What is important here to notice is that a call to addouter() function returns a variable which we call later but still the values of the variables "a" and "b" are hanging around. Think about it this way, the variable result is nothing but the function addinner. Now in the last line, we did invoke the result() function which means we invoked the addinner function which was able to return the values of "a" and "b" variables and it's because of the closure in which it's enclosed.

The concept of closure is a bit difficult to understand if you are reading about it for the first time. Let me give you another reference to understand closure better:

JavaScript
// Global variable "a"
var a = 10;    // Outer function addouter
var addouter = function(){
  var b = 20;
  
  // Inner function addinner
  var addinner = function(){
    return (a + b);
  }
  return addinner;
}    // Call outer function which returns addinner as a variable.
var result = addouter();
// As result variable contains variable addinner which is nothing but a function
// so we have to call result() as a function.
document.writeln(result());

Revealing Module Pattern

So now, we'll use the concepts explained earlier to write a design pattern which is called Revealing Module Pattern.

In the example below, we define an outer function named "Mathlibrary" which will simulate a class in an Object Oriented language. Inside this class Mathlibrary, we'll have certain local variables like count, _add and _sub.

count is a local variable which is used as a counter.

_add and _sub variables are functions but as these are local variables, we can treat them as private methods.

So the variables count, _add and _sub would not be accessible from outside the function Mathlibrary so that means we have encapsulated them inside the class Mathlibrary.

Now what does the Mathlibrary function (representation of a class) return?

As we can see, it returns a JavaScript object in the form of an object literal.

And what does the returned object contain?

It contains 2 properties, "add" and "sub". "add" points to nothing other than the _add variable which is a function to add 2 numbers and also display a counter. Similarly, "sub" points to _sub variable which is a function to subtract 2 numbers and display a counter.

After we defined the function(class) Mathlibrary, we created an instance of it named "mathObj" and later called the 2 public methods, add() and sub().

So in essence, we created a class with 1 private variable, 2 private methods and 2 public methods. This particular pattern is called the "Revealing Module Pattern".

JavaScript
var Mathlibrary = function(){
  // private count variable
  var count = 0;
  
  // private method _add
  var _add = function(a, b){
    count++;
    document.writeln(a + b + "- count = " + count);
  };
  
  // private method _sub
  var _sub = function(a, b){
    count++;
    document.writeln(a - b + "- count = " + count);
  }
  
  // return public method add and sub as a JavaScript 
  // Object literal
  return{
    add : _add,
    sub : _sub
  }
}
// Create an object of Mathlibrary class
var mathObj = new Mathlibrary();
// Call methods add and sub on the mathObj object
mathObj.add(150, 100);
mathObj.sub(150, 100);

Singleton

With the above pattern, we simulated creating a normal class where every time, we new up an object an instance got created. In the below sample, I'll modify the code slightly to create a singleton so that there will be a single instance of the object in memory.

The change done is actually very simple. We have just added a parenthesis() with a semicolon to the function definition of Mathlibrary which will self execute. And as it's self executing, we don't have to new it up and call the methods on it.

JavaScript
var Mathlibrary = function(){
  // private count variable
  var count = 0;
  
  // private method _add
  var _add = function(a, b){
    count++;
    document.writeln(a + b + "- count = " + count);
  };
  
  // private method _sub
  var _sub = function(a, b){
    count++;
    document.writeln(a - b + "- count = " + count);
  }
  
  // return public method add and sub as a JavaScript 
  // Object literal
  return{
    add : _add,
    sub : _sub
  }
}();

// As it is a singleton, we don't need to create an object but can directly call the methods.
Mathlibrary.add(150,100);
Mathlibrary.sub(150,100);

IIFE (Immediately Invoked Function Expression)

We already read about global variables and if we have a look at the above 2 programs that we wrote, we will see that we created a couple of global variables, one for creating the class Mathlibrary and one for creating the instance of the class mathObj. And let me tell you something that you already know, global variables are bad. Yes in JavaScript, it's even worse. Read http://www.oreillynet.com/pub/a/javascript/excerpts/javascript-good-parts/awful-parts.html.

So to avoid global variables, we'll create an IIFE, where we'll wrap the entire code of the Revealing Module Pattern in an anonymous function (a function with no name) and add parenthesis at the end to self execute it (similar to the singleton pattern). And that's it, we have a design pattern with encapsulated members and no global variables.

JavaScript
(function(){
  var Mathlibrary = function(){
  // private count variable
  var count = 0;
  
  // private method _add
  var _add = function(a, b){
    count++;
    document.writeln(a + b + "- count = " + count);
  };  // private method _sub
  var _sub = function(a, b){
    count++;
    document.writeln(a - b + "- count = " + count);
  }   // return public method add and sub as a JavaScript 
  // Object literal
  return{
    add : _add,
    sub : _sub
  }
}
// Create an object of Mathlibrary class
var mathObj = new Mathlibrary();
// Call methods add and sub on the mathObj object
mathObj.add(150, 100);
mathObj.sub(150, 100);
}());

Summary

In this article, we learned one of the very popular design patterns used in JavaScript - the "Revealing Module Pattern".

If you have any questions, please post them below and I'll try my best to answer them. Hope it helps!

History

  • 21st September, 2014: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Wipro Technologies
India India
Currently working with Wipro Technologies as a Technical Consultant. I am primarily a .NET developer/consultant with experience in ASP.NET, ASP.NET MVC 3/4/5, WCF, Windows Azure,Knockout, AngularJS, NodeJS etc. I am interested in keeping myself updated with emerging technologies.

Comments and Discussions

 
QuestionUnnecessarily long but still gold Pin
IntelliSense125-Jan-16 4:07
IntelliSense125-Jan-16 4:07 
QuestionNice article! Pin
George Tourtsinakis21-Jan-16 1:46
George Tourtsinakis21-Jan-16 1:46 
GeneralMy vote of 2 Pin
tornbladswe23-Sep-14 2:59
tornbladswe23-Sep-14 2:59 
BugIncorrect Singleton Pin
Nitij23-Sep-14 0:04
professionalNitij23-Sep-14 0:04 
GeneralRe: Incorrect Singleton Pin
Rajiv Gogoi23-Sep-14 2:42
professionalRajiv Gogoi23-Sep-14 2:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.