Sunday, August 5, 2012

Javascript Anonymous Functions And The Module Pattern

One of the most annoying things about JavaScript is that it has no scope for variables. Any variable, function, array or object you define that is not inside another function is global, which means that other scripts on the same page can access—and will usually override— them.
The workaround is to encapsulate your variables in an anonymous function and call that function immediately after you define it. For example, the following definition would result in three global variables and two global functions:

var name = 'Chris';
var age = '34';
var status = 'single';
function createMember(){
  // [...]
}
function getMemberDetails(){
  // [...]
}

Any other script on the page that has a variable named status could cause trouble. If we wrap all of this in a name such as myApplication, then we work around that issue:

 var myApplication = function(){
  var name = 'Chris';
  var age = '34';
  var status = 'single';
  function createMember(){
    // [...]
  }
  function getMemberDetails(){
    // [...]
  }
}();
This, however, doesn't do anything outside of that function. If this is what you need, then great. You may as well discard the name then:

  (function(){
  var name = 'Chris';
  var age = '34';
  var status = 'single';
  function createMember(){
    // [...]
  }
  function getMemberDetails(){
    // [...]
  }
})();
If you need to make some of the things reachable to the outside, then you need to change this. In order to reach createMember() or getMemberDetails(), you need to return them to the outside world to make them properties of myApplication:

var myApplication = function(){
  var name = 'Chris';
  var age = '34';
  var status = 'single';
  return{
    createMember:function(){
      // [...]
    },
    getMemberDetails:function(){
      // [...]
    }
  }
}();
// myApplication.createMember() and 
// myApplication.getMemberDetails() now works.


This is called a module pattern or singleton. It was mentioned a lot by Douglas Crockford and is used very much in the Yahoo User Interface Library YUI. What ails me about this is that I need to switch syntaxes to make functions or variables available to the outside world. Furthermore, if I want to call one method from another, I have to call it preceded by the myApplication name. So instead, I prefer simply to return pointers to the elements that I want to make public. This even allows me to shorten the names for outside use:

 var myApplication = function(){
  var name = 'Chris';
  var age = '34';
  var status = 'single';
  function createMember(){
    // [...]
  }
  function getMemberDetails(){
    // [...]
  }
  return{
    create:createMember,
    get:getMemberDetails
  }
}();
//myApplication.get() and myApplication.create() now work.

Reffer: "revealing module pattern."
http://coding.smashingmagazine.com/2010/04/20/seven-javascript-things-i-wish-i-knew-much-earlier-in-my-career/