Choosing an Ajax toolkit

Posted by Daniel on February 08, 2008
Programming

Edited to add: Someone pointed out that “Dojo Core” can be considered a base toolkit. I will review Dojo Core along with jQuery in next week’s post.


Today I’d like to shift focus and talk about choosing an AJAX toolkit. Unlike most reviews, I will not do a feature comparison. There are many reviews that do that and I’d bring nothing new to the table. Instead, I will talk about aspects which I consider very important but are overlooked by a mere feature comparison:

  • Does the toolkit try to change the character of the language?
  • Does the toolkit make good use of JavaScript features?
  • Does the toolkit help you learn to use JavaScript as it was designed?
  • Does the toolkit introduce the risk of breaking valid JS code?
  • Does the toolkit smooth out cross-browser incompatibilities or does it add new ones?

These issues are subjective and hard to assess, but are nonetheless very important. JavaScript is a very powerful but very unique language. Using a toolkit that denies the nature of JavaScript and tries to kludge it into behaving like something it’s not is to deny yourself the opportunity to learn the full power of the language.

I’ll quickly divide AJAX toolkits into two groups:

Base Toolkits
Light weight. They include core functionality like DOM tools, utility functions, etc but for example, no GUI widgets. Examples include Prototype, MooTools, jQuery and Mochikit.
GUI frameworks
Heavy weight. They include GUI widgets like trees, tabs, dialogs and drag and drop. Examples include Dojo, YUI, Ext and Script.aculo.us.

These two groups are very different and should not be compared directly. Yes, the distinction is not clear cut, but you have to draw a line somewhere. In this post I will only look at base toolkits. I might look at the GUI toolkits another time.

Skip to: Prototype | MooTools | Mochikit | jQuery

Prototype (up ^)

Prototype is a popular AJAX toolkit and its supporters are not going to like what I have to say about it. The problem is that it:

  • Pollutes the global namespace with many functions.
  • Modifies base classes of JavaScript.
  • Tries to change the nature of the language.

I have a big problem with libraries that modify the JavaScript base classes. These extensions are not necessary (jQuery is living proof). For example, would you like the Array object to have an “each” method? Sure. But we don’t need to extend the Array object to do that. Look at how jQuery does it:

// jQuery
$(myArray).each ...

// Prototype
myArray.each ...

jQuery’s version only adds 3 characters and it leaves the base class intact.

What’s wrong with extending base classes? It can break existing valid code, it can break other libraries, it makes the library less portable and it makes it harder to tell which features are part of JavaScript and which were added by the library.

Consider the following code for example:

var myFriends = ["Joe", "Janet", "Jason", "Jess"];
for (var i in myFriends) {
	... do something with myFriends[i] ...
}

This is valid JavaScript and Prototype will break it. Ok, there are reasons why you might want to avoid for-in loops altogether, but that doesn’t excuse Prototype breaking valid JavaScript.

In addition, some of Prototype’s changes are not cross-browser. Cross-browser programming is hard enough as it is, and one of the things I look for in an Ajax library is to smooth-out differences, rather than add more of its own.

Prototype doesn’t just extend base classes, it tries to fundamentally change the nature of the language. For example:

The Hash() object

Why do we need a Hash() object? JS Objects already provide this functionality:

/* Prototype */
var myHash = new Hash();
myHash.set('name', 'Bob');
myHash.set('age', '21');
var name = myHash.get('name');

/* JavaScript */

// Option 1
var myObj = { name: 'Bob',  age: 21 };
var name = myObj.name;

// Option 2
var myObj = {};
myObj.name = 'Bob';
myObj.age = 21;
var name = myObj.name;

All you have done is modify the language to look more like Java. Getter and Setter methods are a Java-ism because Java objects work fundamentally different from JavaScript objects. They are rarely the best solution in JavaScript.

Classes

Prototype tries to force classes into JavaScript:

var Person = Class.create({
  initialize: function(name) {
    this.name = name;
  },
  say: function(message) {
    return this.name + ': ' + message;
  }
});

But JavaScript doesn’t need classes. JavaScript is a fully OOP language, it just has no classes. JS has lambdas, closures and prototypal inheritance and a very powerful object system. These are extremely powerful features and they solve the problems that classical inheritance is meant to solve.

See also:

Summary: Prototype can introduce bugs, doesn’t play well with other libraries, changes the character of the language and inserts new cross browser incompatibilities. I don’t like it.

MooTools (up ^)

My feelings about MooTools largely echo those about Prototype. Like Prototye, MooTools modifies base classes with similar consequences as Prototype. In particular, MooTools and Prototype cannot co-exist in the same program.

It’s not that I enjoy mixing libraries, but I expect that any well-designed library be properly encapsulated and can be added to an existing application without introducing bugs. Basic encapsulation is very fundamental. We wouldn’t tolerate this behaviour in Java or Python, why should we tolerate it in JavaScript?

MooTools also pollutes the global namespace with its own functions. I believe that libraries should contain all their functions inside a single namespace and not touch anything outside it. That ensures that the library plays well with other code.

MooTools also tries to emulate class inheritance in JavaScript, but over-all they don’t seem to try as hard to make JavaScript into some other language. I do understand that a lot of people want this kind of emulation, so I don’t hold that against the library.

Summary: Much better than Prototype based on my criteria, but I still have issues with a library extending base classes and inserting global functions.

Mochikit (up ^)

I like Mochikit, I really do. It does not extend base classes and does not seem to try to change the character of JavaScript. It does insert new global functions, and I wish it didn’t. But Mochikit is nonetheless a library that I would be quite happy to use in my programs.

Mochikit appears fairly well documented. That said, I’m concerned that I could not find any tutorial-style (task-oriented) documentation which is important for new users. Task-oriented documentation is very important and regularly overlooked.

Here is a code sample from Mochikit. It demonstrates DOM manipulation:

var rows = [
    ["dataA1", "dataA2", "dataA3"],
    ["dataB1", "dataB2", "dataB3"]
];
row_display = function (row) {
    return TR(null, map(partial(TD, null), row));
}
var newTable = TABLE({'class': 'prettytable'},
    THEAD(null,
        row_display(["head1", "head2", "head3"])),
    TFOOT(null,
        row_display(["foot1", "foot2", "foot3"])),
    TBODY(null,
        map(row_display, rows)));
// put that in your document.createElement and smoke it!
swapDOM(oldTable, newTable);

We see several new global functions (TABLE, TR, THEAD, TBODY, TFOOT, map, swapDOM). Otherwise, I like the code. Notice that Mochikit does not try to invent its own arrays or hashes. I saw this a lot while reading the Mochikit code samples. They use the native JavaScript objects throughout.

I was pleasantly surprised that I could not find any functions that try to push classical inheritance into JavaScript. Instead, I found several functions for functional programming (partial, map, filter) and even prototypal inheritance! (merge). I’m impressed.


Edited to add:

Mochikit has a very interesting set of tools called MochiKit.Iter, which provide additional functional programming features like lazy iterators. Lazy evaluation is a powerful feature of functional programming.

I’m pleased to see that Mochikit has paid attention to the functional aspect of JavaScript. Functional programming is one of the sources of JavaScript’s power and I like to see a toolkit that encourages this approach to programming.


Summary: Mochikit is the first library I actually like and would recommend. It does not try to make JavaScript look like something it’s not. Instead it builds on JavaScript’s strengths like functional programming and its powerful objects. My only complaint is that the functions are not contained inside a namespace, and there are no tutorials. But I loved everything else about Mochikit.

jQuery (up ^)

I owe you this one. I promise to add a review for jQuery soon. At first sight, I like it a lot. It seems to make good use of JS features, and its functions are contained in a namespace. But I don’t have enough time today to give it justice.


Edited to add:

Next week I’ll also try to cover Dojo Core. Dojo Core is a subset of Dojo which can be considered a “base toolkit” in its own right.


2 Comments to Choosing an Ajax toolkit

jhuni
October 8, 2009

In regards to MochiKit, when you say “It does insert new global functions, and I wish it didn’t.” Note that it is easy to make it so that you don’t export the 242 functions of the library, and in fact it is built so that it doesn’t force those on the user, and all the plugins are structured that way as well.

Daniel
November 3, 2009

Thanks for the info. I’m still not a fan of libraries that insert global functions. I’m glad you can turn it off, but I’d be happier if it was off by default.

Leave a comment

WP_Big_City

Buy cheap softwarebuy adobe softwaredownload software software sales oem software