YUI’s “Module Pattern” vs. Prototype’s Class Function

Via Geoffery Moller, I came across this article on Matt Snider’s blog. I’m surprised that no one noticed what (to me) was the most relevant difference in the libraries that he evaluated.

The “YUI method of class creation” is not distinctively YUI—it’s just what Javascript gives you for free. You can use the “Module Pattern” alone on a page with no library at all! You can call it Crockford’s Module Pattern, but it seems to me that he discovered or popularized it more than “invented” it.

This, to me, highlights the biggest difference in approach between YUI and every other library: YUI doesn’t attempt to re-write the language, but rather to show off what the language can do and how those features can be effectively put to use. My experience with Prototype and Dojo and Mochikit all made me feel a bit like the author must not have liked Javascript very much. (Dojo actually goes a bit further—it rewrites HTML as well!) It seems like the other libraries say, “This Javascript language is too hard and confusing. Let’s make it into something else.” YUI says, “This language is beautiful and powerful, but it would be handy if we had some conventions and a common approach to these rough edges. Let’s build those common pieces.” It’s the difference between teaching someone to fish and giving them a fish, except instead of giving him a fish, you pass the fish through a slow and complex machine that spits out Java code.

Of course, I’m a bit biased. I imprinted upon YUI at a fairly early stage in my Javascript development. I work here, so I get to request features directly through our internal bugzilla instead of pleading in the public arenas. But the approach is one that I’ve always favored. If you feel the need to rewrite the language, then just go use another language. Javascript is the common tongue of the internet, and will remain so for the indefinite future. Don’t fight it. (Hat-tip to Jeff Atwood.)

Crockford’s “Module Pattern” is a great way to create a singleton that has some private methods. In fact, in my opinion, it’s the best and only way that this task should be done. (There are others, but they tend to be more obtuse, IMO.) But that’s not the only task of an object-oriented development. Sometimes, you need to have a bunch of objects, and if they have shared functionality, then that should be handled with a class of sorts. In Javascript, that means that they’re stamped from the same Constructor and Prototype. The Module Pattern does not address this in a very clear way, but it does highlight the principle of data-hiding through a closure that is the key to OOP in Javascript.

To create a class, I usually do something like this, which takes the essence of the Module Pattern and uses it to create a reusable class.

(function () {
  // these are properly private static, not just private
  // but with scope correction, that’s good enough for functions.
  // private function, called with privateFunction.call(this, a, b, c);
  var privateFunction = function (a, b) {
    this.a = a;
    this.b = b;
  };
  // private static data. Shared between all instances!
  var privateStaticData = “I’m private and static. All instances share me.”;
  YAHOO.myProject.myClass = function (a, b, id) {
    // a and b are public, since they’re set on this.
    this.a = a;
    this.b = b;
    YAHOO.myProject.myClass.instances[id] = this;
  };
  YAHOO.myProject.myClass.instances = {};
  YAHOO.myProject.myClass.prototype = {
    myPublicProperty : “I’m accessible as .myPublicProperty.”,
    myPublicMethod : function () {
      var a = (new Date()).getTime();
      var b = a + 10000;
      // note the way that private functions are called.
      privateFunction.call(this, a, b);
    }  
  };
})(); // close the closure and execute the code.
// later on…
(function () {
  var myInstance = new YAHOO.myProject.myClass(1,2,’blahblah’);
  // now you can deal with it as “myInstance” within this closure,
  // or as YAHOO.myProject.myClass.instances.blahblah elsewhere.
})();

(When in doubt, wrap it in a closure. Global variables are evil.)

I’d rather work with someone who is a bit green with Javascript but can learn, rather than someone who is an expert with Prototype or Dojo. The more time someone spends building applications with a library like Prototype, the further they get from Javascript, and the more dependent they become on the library. By contrast, time spent using YUI tends to breed developers who are experts in Javascript, and that skill is far more useful than being an expert in a particular library.