Prototype Framework is a Javascript Extension, Not Just a Library


I recently ran into a problem with Prototype (the Javascript framework) that exposes a big difference between the design philosophy of Prototype and other frameworks like JQuery.

Consider this code:

var aryOmnDiv = [
   'header_tracking',
   'left_nav_tracking',
   'footer',
   'homepagecategories',
   'subcats',
   'bread_crumb',
   'subcat_wrapper',
   'prod_group_wrapper']; //container divs

for(var outside_i in aryOmnDiv) {
   var divname = aryOmnDiv[outside_i];
   var div = $(divname);
   if(div) {
\tvar anchors = div.getElementsByTagName('a');
   }
}

Running this with Prototype installed produces and error that says "getElementsByTagName is not defined." The culprit is that the code is using a for...in loop as a shortcut for looping through the array. The official ECMAScript standard says (ยง12.6.4) that the for...in construct exists to enumerate the properties of the object appearing on the right side of the in keyword. It's only an accident that it also worked for looping through arrays because stock arrays have a sparse property set in Javascript.

The problem is that Prototype changes that adding dozens of new properties (functions mostly) to the Array object. This means that the loop above gets past the Array indices and keeps on going, setting outside_i to each of the Array properties in turn. Of course, those aren't valid array indices and so the code eventually errors out.

As explained on the Prototype site, this can easily be fixed by changing this line:

for(var outside_i in aryOmnDiv) {

to this line:

for (var outside_i = 0; outside_i < aryOmnDiv.length; ++outside_i) {

Alternately, you could make use of the nifty new iterators that Prototype adds to Array like each.

I think I remember reading about this on the Prototype site before but it didn't mean much to me until I ran into it and spent some time looking at it.

This problem points out a fundamental difference in the design philosophy of Prototype and other frameworks like JQuery. Prototype extends base objects (like we've see with Array) whereas JQuery doesn't. Put another way, almost all of the new functionality in JQuery is neatly sandboxed in the JQuery namespace whereas with Prototype that's impossible.

The extensions that Prototype makes to Arrays are nice. I've used them and like the coding style, but be aware that this isn't a neatly packaged library that plays nicely with other Javascript you might already have. It's a change to Javascript itself yielding a new thing. Very cool that Javascript allows that, but be careful not to shoot yourself in the foot.