Array.forEach – The genericity potential

In the previous article we discovered the .forEach method and the others Array methods normalized by ECMAScript 5.

.forEach() natively out of the DOM

This is interesting, but it seems to be limited. Indeed, unless you are writing some mathematic library in JavaScript, you usually don’t manipulate Array, but rather Array-like objects such as HTMLCollection or NodeList you got from document.getElementsByTagName('a'), querySelectorAll('.tab') or table.rows.
Sadly, non of these interfaces is an ECMAScript Array. (see ECMAScript bindings for DOM Core Level 3 and DOM HTML. Actually, the word “Array” doesn’t appear a single time in any of these documents.

A natural consequence is that the following code raises an error :

var cells = document.getElementsByTagName('td');
cells.forEach(function(e,i,a){
                    e.style.backgroundColor = randomColorString(); 
                    // randomColorString has been previously defined
                   });

This is quite sad but that’s another debate.

ECMAScript 5’s good idea

About the forEach method and other Array methods, the specification states the following :

NOTE : The forEach function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method. Whether the forEach function can be applied successfully to a host object is implementation-dependent.

After a closer look at the forEach specification, it turns out that this method could be used on any object with a length property and having properties with 0..(length-1) as identifiers. This last condition is not necessary, but corresponds to forEach semantics.

Let’s try !

getElementsByTagName is not standard-compliant on Firefox, but even with the following code inserted before the above one :

NodeList.prototype.forEach = Array.prototype.forEach; // For standard-compliant browsers
HTMLCollection.prototype.forEach = Array.prototype.forEach; // For Firefox which consider that getElementsByTagName returns an HTMLCollection

The previous background-color randomizing code works. (Note : It didn’t on Firefox 3.5, but does on Firefox 3.6). I have also tested on Opera 10.61 and Chrome 5

Fantastic idea from the TC39 ECMA committee (people who wrote ES5) to have the array extra methods generic to make them transferable to other objects.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s