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.

8 Comments

  1. matt snider

    Posted Mon 2007-08-13 @ 12:03:48 | Permalink| Reply

    Great post Isaac. I could not agree more ^_^

  2. Nate Koechley

    Posted Mon 2007-08-13 @ 13:52:50 | Permalink| Reply

    Well said - I’ll be pointing people to this post for sure.

    Thanks,
    Nate

  3. Isaac

    Posted Mon 2007-08-13 @ 16:06:21 | Permalink| Reply

    Thanks for the props, guys.

    @Nate I think I just figured out a promotion technique for Foohack: write about YUI every other post, and let you promote it for me. :)

  4. Denis

    Posted Thu 2007-08-23 @ 19:35:23 | Permalink| Reply

    Take a look at jGrouse Loader http://jgrouse.com/#jgrouselib/jgloader.html - it is the logical extension and implementation for the concept of JavaScript module. Normally you would expect that modules would track dependencies on each other and have a predictable initialization order - jGrouse Loader provides that functionality. And you can use it with any other library that you’re currently using.

  5. Animal

    Posted Sun 2007-11-18 @ 02:48:16 | Permalink| Reply

    I don’t see the point of creating the constructor in the anonymous function. If the public instance methods (in the prototype) need to use private (inaccessible to others) variables, just have the *prototype* returned from an anonymous function:

    MyClass= function(a, b, id) {
    };
    MyClass.prototype = (function() {
      var privateData = “foo”;
      function privateMethod() {
      };
      return {
        publicMethod: function() {}
      };
    })();

  6. Isaac

    Posted Sun 2007-11-18 @ 12:36:23 | Permalink| Reply

    @Animal

    That works just as well, I suppose, except that the private methods can’t be accessed from within the constructor itself. On the other hand, the benefit is that, for those familiar with the javascript module pattern, it uses the module pattern to create the prototype.

    Of course, they’re so cheap that when in doubt, I just create a closure to hide code within it. They you can afford to be a bit “sloppy” (creating vars willy-nilly) without fear of polluting the global space.

  7. Fred

    Posted Sun 2008-04-27 @ 02:34:50 | Permalink| Reply

    To properly compare frameworks and libraries one must become very proficient in each library. That means write several applications in each. Or, more fairly, write the same application in each. Perhaps the old Pet Store.

    By the time you’re done the libraries will have evolved and the critics will say you’re using out-of-date software. Then, of course, you will have used up far more time than you have available, and a major purpose for using the library was saving time in the first place!

    Rational comparison is irrationally expensive.

    Fred

  8. Isaac

    Posted Thu 2008-05-01 @ 01:53:48 | Permalink| Reply

    That’s a very good point.

    In all fairness to Prototype, I haven’t used it nearly as extensively as I have YUI, and it does provide some very nifty syntactic sugar. What’s worse, I personally know a lot of the people involved with YUI, and I’m sure that my high opinion of them as people colors my feelings about their work, even if I try my best to be unbiased.

    However, I *can* say that I’ve interviewed and known with many Javascript developers who have worked with Prototype and Dojo. Take away their $, and most of them are useless. We internalize the paradigms we surround ourselves with. By comparison, I’ve also seen complete javascript novices (including a few non-yahoos) start using YUI, and by adopting the paradigms in the library, become much better javascripters.

    The fundamental reason for this is obvious: YUI was created with the intent of extending the paradigms within the javascript language. Most other libraries were created with the intent of changing the paradigms of the language. You can’t learn russian by speaking french.

    There comes a time in a project, hopefully as soon as possible, when you pick a framework and run with it. That decision is never fully informed, because that would make it pointless. The quality of the community and the documentation is key. In my opinion, YUI is a better library largely because it fosters a community that tends to be more knowledgeable about javascript in general, and because code that uses YUI will tend to be more understandable by anyone who knows Javascript.

    Dojo’s chaining syntax is pretty and clever, but if you aren’t familiar with Dojo, it can be rather confusing. On the other hand, YUI’s structures, and the code that implements them, while a bit more wordy than Dojo, are also very clear, easy to optimize, and easy for any javascripter to understand, even if they’re not already familiar with YUI.

One Trackback

  1. Posted Mon 2007-08-27 @ 10:01:07 | Permalink| Reply

    [...] did recently compare YUI with a competitor, and I don’t want this to turn into a “YUI vs. X” blog. It’s a very limited [...]

Post a Comment

Post Friendly. About