Module Pattern in Javascript

Module pattern in Javascript

The Module Pattern is what we’d call a “design pattern” in Javascript. It keeps our source code simple and easy to read and use.
The Module Pattern is the most commonly used design pattern and widely accepted in number of large projects such as jQuery, Dojo…


Creating a module

We’ll create an anonymous function and calls itself immediately.

(function() {
  // code
})();

Statements that begin with function are always considered to be function declarations and including () creates a function expression.

After creating new scope, we need to namespace our code to access inside the module.

var Module = (function() {
  // code
})()

Public and Private methods

Now we can create any method inside our module and use return to return an Object to Module.
For example we create a public method which is accessible from the outside.

var Module = (function() {
  return {
    publicFunc: function() {
      // code
    }
  }
})()

We’re returning Object Literal then from outside, we can call that method like

Module.publicFunc()

Actually, Javascript doesn’t strictly have private method but we can implement by hiding things that we don’t want people can call it outside the scope of our module.

var Module = (function() {
  var _privateFuncOne = function() {
    // define a locally function
  }
  var _privateFuncTwo = function() {
    // it's only use inside our module
  }

  return {
    publicFunc: function() {
      // we can call private function here, you know
    }
  }
})()

It’s better to use prefix naming convention for private method, it’s easy to read the code when our module has a lot of functions.


Module structure

Depending on your project, you can defined and structured your module as some ways below.

Anonymous Object Literal

It’s the easiest way to return an anonymous Object Literal.

var Module = (function() {
  var _privateFunc = function() {
    // code
  }
  return {
    publicFuncOne: function(params) {
      // code
    }
    publicFuncTwo: function() {
      // code
    }
    publicFuncThree: function(params) {
      // code
    }
  }
})()

Locally scoped Object Literal

var Module = (function() {
  var myService = {} // init an locally scoped object

  // Define private function        
  function _privateFunc() {
    // code
  }

  // Define public function
  myService.publicFunc = function() {
    // code
  }
  return myService; // At last, we return our defined object
})()

It’s easier to see what is public or private because public method has locally scoped object attached myService.publicFunc
The Module won’t care about the name of myService because we return the actual an object.

Revealing Pattern

It’s help the syntax of our scripts are even more consistent and explicitly defined public methods and variables which lead to increased readability.

var Module = (function() {
  var _privateFunc = function() {
    // private
  };
  var someFunc = function() {
    // public
  };
  var anotherFunc = function() {
    // public
  };
  return {
    someFunc: someFunc,
    anotherFunc: anotherFunc
  };
})();

Extending Module

Now we have very nice Module, we can even more augmenting this module by extends it.
We create another module named OtherModule extended from our previous Module

var OtherModule = (function(Module) {
  Module.extensionFunc = function() {
    // code
  }
})(Module || {});

Firstly, we need pass Module namespace to OtherModule to get accessible. After that, we easily to create an extension method which was add into Module and return.
Finally, OtherModule has three method, two of them extended from Module which are someFunc, anotherFunc and a new one just have been created which is extensionFunc.

The keyword Module || {} for the error case, that means if Module is undefined we will not have any problem here.


Conclusion

Advantages

  • Cleaner approach for developers
  • Supports private data
  • Less clutter in the global namespace
  • Localization of functions and variables through closures
  • The syntax of our scripts are even more consistent

Disadvantages

  • The power to have private methods and variables can be abused
  • Extending objects is unclear
  • Object identities is unclear – instanceof doesn’t work.

 

Add a Comment