jQuery: so close...and yet...

January 22, 2009

So I’m finally, officially making the switch for real this time from Prototype to jQuery. I’d been meaning to learn it anyway, and since it’s the lingua franca of my new job, I figured now is a good time. The experience has been good: documentation is excellent and things are fast, easy and require a minimum of effort. And yet...and yet...I can’t help missing Prototype; or at least some parts of it. Let me draw an analogy with espresso makers:


On the left, you see a Gaggia 77001. On the right, a Capresso C1300. The Capresso is a nice machine: it makes good espresso, it’s fast, and it’s easy to use. The Gaggia is a little trickier: you have to pull the lever with a steady, correct pressure and because you control the rate at which water goes through the machine, it’s easy to over- or under-pull a shot. However, it makes superb espresso. 

If that comparison comes off as snobbish, sorry. I didn’t mean it that way. The fact is, a lot of the time, the Capresso is the way to go. I love espresso, but I certainly wouldn’t want to fire up the Gaggia every morning. I’ve got places to go, things to get done and I want a decent cup of espresso while I’m doing it. 

What was I saying?

To get back to javascript, jQuery has suberb DOM selection and traversal methods. It’s event handling is well designed and fluent and it gives you some some better iterators than plain-ol’-JavaScript. (By the way, if you’re using “for...in” to iterate over anything other than object properties: stop it!) Finally, it has animation! Prototype doesn’t have that, you’d need Scriptaculous or somehting. 

Prototype, by contrast, has slightly clunkier DOM-handling functions. Compare this in jQuery:


$(“a”).click(function() { alert(“Ah! You clicked me!”); })

To the same thing in prototype:


$$(“a”).invoke(“observe”, “click”, function() { alert(“Ah! You clicked me!”); })

Not a big difference, but this stuff adds up. That example also shows something nice about jQuery: it’s implicit iteration. You can call click on a single DOM element or a hundred. Other areas really show Protoype at a disadvantage. For example:


 $(“body”).wrap(“<div></div>”);

Is much nicer than Prototype’s:


 var wrapper = new Element(“div”);
 $$('body')[0].childElements().each( function(el) {
	 wrap.appendChild(el);
 });

“So”, you’re probably asking, “what’s wrong with jQuery? Sound great.” 

The downside

For some things, Prototype be a little clunkier than jQuery but the converse is that there are many things that Prototype can do that jQuery can’t do at all*. Typically, these are things that make programmers happy. 

  • Prototype handles JSON: string methods like “isJSON” and “evalJSON” to parse, and a “toJSON” method for every javascript type to serialize. 
  • Prototype gives you classes (for those who still have their struggles with prototype-based inheritance, like me). 
  • It extends basic data types like object and array, to provide all kinds of convenience. 
  • jQuery gives you one all-purpose iterator, “each”, and some methods like “map” and “reduce” that only work on a jQuery object. Meanwhile, Prototype gives you  26 methods for working with lists of anything, part of Prototype’s desire to give JavaScript users all the flexibility of Ruby when it comes to lists. 
  • It serializes the contents of HTML forms to a JavaScript object, so you can do something like this:
    
    data = $(#my-form”).serialize(true).toJSON;
    Ajax.request(url, {‘method’: POST, ‘postBody’: data})
    
  • And it extends the function prototype to give you all sorts of useful methods. You can wrap and curry functions on your own,  but Prototype makes it as simple as:
    
    add = function(n1, n2) { return n1 + n2);
    addThree = add.curry(3);
    

You might argue “what’s the use of all this stuff?” For smaller projects, or if the UX of your site isn’t too complex, it probably doesn’t matter But once your JavaScript code base starts to get big (say 1000-2000 LOC) you start to really appreciate this stuff. It promotes code reuse, organization and inheritance. In other words, Prototype is a programmer’s library.

I realize this is a controversial assertion. In my next post, I'll delve into a particular area where JQuery is poorly designed in a way that makes writing object oriented code hard, which I think will illustrate my point.

* I will  mention animation again though: that’s the only area where Prototype simply lacks any functionality that jQuery has. But there is always Scriptaculous and some other, more light-weight (and less frustrating) Prototype extensions for that. 

Tagged with: , , .

Leave a comment:

Comments are closed for this entry. There are 2 comments for this post:

name:
dz
date:
Jan 23, 2009 06:02 a.m.
comment:
jQuery does lack some things in its core, but one of the its big strengths are the things that can be built on top of it, while still taking advantage of the things it does well. For example, for classes, there's Class Query (http://ejohn.org/blog/classy-query/), for JSON, there's a number of plugins (such as http://code.google.com/p/jquery-json/), and it should be realatively straight forward to implement a jQuery.curry method (Ariel wrote one at http://demos.flesler.com/Curry/) if you need it. Or even something more robust like a proper jquery-functional library. Prototype is prety nice, but there are some parts of it that bother me conceptually (including aliasing just to give comfortable synonyms; feels like stepping a little back into Perl and TIMTOWTDI). Admittedly, I haven't seriously used it in nearly 2 years now, so things probably have changed since then. In any case, the javascript world changes fast, and there's no reason to dive headfirst into jQuery to the exclusion of prototype if you have reservations. It's only lingua franca due to common consent -- but like all things, it's up for debate. Although, I suppose in the worst case scenario, you can use prototype and jQuery at the same time with jQuery.noConflict().
name:
test
date:
Jan 23, 2009 06:06 a.m.
comment: