JavaScript Module Pattern Variations

31st August, 2007 @ 9:02am UTC

Development, JavaScript, Tutorials, Web / 5 Comments

The JavaScript Module Pattern is a handy pattern for JavaScript singletons. It allows a developer to scope variables and methods to a given module with both private and public visibility.

Originally proposed by Douglas Crockford (and blogged on the YUI blog by Eric Miraglia), the Module Pattern has recently been through several iterations of pimpage (look Ma — a new buzzword!) at the hands of Christian Heilmann; the first entitled “Show love to the Module Pattern” and the second, “Again with the Module Pattern“. Before reading this post, I’d recommend you read all of these articles otherwise this is going to make very little sense!

Having used the pattern quite regularly over the last six months or so, I’d like to add my two-pennies-worth to the discussion with a couple of variations on the theme…

Module Pattern in the Pub

One of Christian’s evolutions of the Module Pattern involves creating an object entitled pub as a private member of the module. This is then returned as public instead of the anonymous object that Douglas first proposed. I’m a big fan of this method because it solves a large number of namespace issues when it comes to dealing with private and public members from within our module. Once again, this is all explained in greater detail in Christian’s post.

The one thing I wasn’t too keen on, when Christian showed me his method, is the fact that we lose a level of indentation — something that Christian actually quotes as a positive feature. I guess this comes down to developer preference but I’ve always liked the fact that that level of indentation allows me to differentiate between the private and public space of the module.

With this in mind, here’s my slight variation on Chris’ original theme:

NEF.FridayDrinks = function () {
  function purchaseBeer() {
  }

  function drink(beer) {
  }

  var pub = {
    sobriety: 10,
    getRoundIn: function(peoplecount) {
      var trayOfDrinks = new Array();
      for (var i = 0; i < peoplecount; i++) {
        trayOfDrinks.push(purchaseBeer());
      }
      return trayOfDrinks;
    },
    getSlyOne: function() {
      drink(purchaseBeer());
    },
    getDrunk: function() {
      do {
        pub.getSlyOne();
        pub.sobriety--;
      } while (pub.sobriety > 0);
    }
  };
  return pub;
}();

var drinks = NEF.FridayDrinks.getRoundIn();
NEF.FridayDrinks.getSlyOne();
NEF.FridayDrinks.getDrunk();

The difference between my method and Christian’s is that, where Chris declares an empty pub object with the object literal and then declares each public method as a property of pub, I declare all public methods within the pub object. It’s a tiny tiny difference, but it brings back that level of indentation we lost without losing any of the added usability of Christian’s method.

Module Pattern Curry

Often, when working with the Module Pattern, you’ll find yourself with only a single public method — usually some form of initialisation script (and, funnily enough, usually called “init”). This is because there isn’t often a need for multiple public methods as most modules are fairly self-contained.

For this reason, I decided to try returning just the method itself; much like I would if I was currying my JavaScript function (although not exactly the same way; for more info check out “Curried Javascript” on svendtofte.com). In this case, we no longer create that public object and, as a result, save a little bit of fuss (and possibly, a little bit of memory too — bonus!), and for all you filesize facists, you’ve knocked out a few lines of code too.

Here’s an example:

NEF.MakeTeaNotLove = function() {
  function getMug() {
    …
  }
  function addTeabag() {
    …
  }
  function addBoilingWater() {
    …
  }
  function addMilk(amount) {
    …
  }
  function addSugar(amount) {
    …
  }
  function stir() {
    …
  }
  return function(milk, sugar) {
    getMug();
    addTeabag();
    addBoilingWater();
    addMilk(milk);
    addSugar(sugar);
    stir();
  };
}();

NEF.MakeTeaNotLove(1, 3);

As you can see, when we call the Module Pattern, rather than having to call an init() member, we can just pass the parameters straight to the returned function. Nice.

Summary

Obviously, one of my examples is only suitable for a particular implementation, and the other simply comes down to developer preference, but hopefully somebody out there will find either one of them useful in some way.

Ultimately, it just goes to show how potentially versatile the JavaScript Module Pattern really is. In a matter of months there have been a number of reworkings, bastardisations, and variations. This is just the sort of thing I love about the JavaScript community — the evolution of code.

Like this post? Digg it or Del.icio.us it!

Comments (5)

Skip to the comment form…

  1. Gravatar Image Alex-o-tron August 31, 2007 @ 10:26 am

    Hi Tim :)

    Have you found a way to mix your return function with the “aliasing” illustrated by Christian?

    Like in :

    return {
        init:publicFunction,
        count:publicVar,
        increase:anotherPublicFunction,
        current:getCurrentState()
      }
    
    versus
    
    return function(milk, sugar) {
        getMug();
        addTeabag();
        addBoilingWater();
        addMilk(milk);
        addSugar(sugar);
        stir();
      };

    Also, anyway with your return function to access a set of “public” methods?

  2. Gravatar Image Tim August 31, 2007 @ 11:04 am

    @Alex: I think the return function should really only be used when you’re sure you have a single “public” method — it’s not really suited to a situation where you could use the “aliasing” method.

    If you’re going to need to return more than one “public” method, then you’re going to require an object.

  3. Gravatar Image Alex-o-tron August 31, 2007 @ 12:03 pm

    Trying a mix of both maybe? So that individual public methods can be accessed and the global one still used. Do you think that would work?

    function getMug() {}
    function addTeabag() {}
    function addBoilingWater() {}
    function addMilk(amount) {}
    function addSugar(amount) {}
    function stir() {}
    return {
      alias1:stir,
      alias2:addTeabag,
      [...]
      do_it_all_alias:function() {
        getMug();
        addTeabag();
        addBoilingWater();
        addMilk(milk);
        addSugar(sugar);
        stir();
      }
    }
  4. Gravatar Image Idetrorce December 15, 2007 @ 1:20 pm

    very interesting, but I don’t agree with you
    Idetrorce

  5. Gravatar Image Dan June 9, 2009 @ 10:21 am

    Please consider the following modular javascript pattern:-

    NameSpace.PluginName = (function() {
      var PrivateMember1 = function() {...};
    
      return {
        PublicMember1: {
          add: function() { ... },
          remove: function() { ... }
        },
    
        PublicMember2: function() {
          ...
        }
      };
    })();

    The plugin is augmented to my dollar sign method, so that all public members are accessible via i.e. $(elementid).PublicMember2() or $(elementid).PublicMember1.add() etc.

    You can reference $(elementid) from within PublicMember2 using the keyword ‘this’. The problem is how do I reference $(elementid) from within PublicMember1.add() or PublicMember1.remove() as the keyword ‘this’ refers to object PublicMember1. I need something like ‘this.this’ or ‘this.parent’, don’t know. HELP

    Thanks in advance

Leave a comment





Categories

Syndication

Technorati

© 2010 Tim Huegdon, All Rights Reserved / Website design and development by Nefarious Designs

Powered by Wordpress / Log in

This website contains no artificial colourings or preservatives. Just 100% WIN.