[whatwg] Adding ECMAScript 5 array extras to HTMLCollection

On Sat, Apr 24, 2010 at 10:50 PM, J Z <kangax.dev at gmail.com> wrote:
> On Fri, Apr 23, 2010 at 10:30 PM, David Bruant <bruant at enseirb-matmeca.fr>
> wrote:
>>
>> Hi,
>>
>> In the HTML5 "status of this document" section, one can read : "This
>> specification is intended to replace (be the new version of) what was
>> previously the [...] DOM2 HTML specifications."
>> This spec can be found here : http://www.w3.org/TR/DOM-Level-2-HTML/
>>
>> It defines ECMAScript language Binding
>> (http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html). This
>> document explains how to implement the DOM HTML interfaces in an
>> ECMAScript-compliant environment.
>>
>> Because HTML5 is intended to replace DOM2 HTML, it can "freely" change
>> ECMAScript bindings. My suggestion is the following :
>> Make that HTMLCollection (and all HTML*Collection, as a consequence of
>> inheritence of HTMLCollection) inherit from the ECMAScript Array prototype.
>> This way, it will make available all Array extra methods (forEach, map,
>> filter...) added in ECMAScript5 (and next versions which should go in the
>> same direction).
>>
>> As far as I know, adding this won't break any existing code. The semantics
>> of a Collection and the way it is used is very close from ECMAScript Arrays.
>> I don't think that the notion of "live object" and ECMAScript Array are
>> incompatible either.
>> Once again, I am talking about ECMAScript binding. I have no intention to
>> touch the HTMLCollection interface or other languages bindings.
>>
>> Would the WHATWG have the power to decide something similar regarding
>> NodeList ?
>>
>> Any thoughts ?
>>
>> Thanks,
>>
>> David
>
> As far as I can see, liveness of HTMLCollection actually does matter. When
> iterating over HTMLCollection, it's more or less a rule of thumb to "save"
> length, to avoid any kind of mismatch (in case code within loop modifies
> document and so affects length of collection in question):
>
> for (var i = 0, length = collection.length; i < length; i++)
> // instead of:
> for (var i = 0; i < collection.length; i++)
>

Actually, the former is a problem when the nodelist is modified in the
loop; it may result in collection[i] being undefined.

The reason for storing length can only be to save a few milliseconds
in checking it each time i.e. "get the length property".

> If HTMLCollection was inheriting from Array, and methods like `forEach`,
> `map`, etc. were to operate on a live object, there would definitely be
> undesired consequences. We can see this in, say, Firefox (which allows to
> set [[Prototype]] of `HTMLCollection` to `Array.prototype`):
>
> HTMLCollection.prototype.__proto__ = Array.prototype;
>

Scary.

> document.getElementsByTagName('div').forEach(function(el) {
> ? el.parentNode.removeChild(el); // doesn't work as expected
> });
>

Removing a child div of an already removed div seems a bit odd, but whatever.

> // turning live collection into static array fixes this
>
> Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
> ? el.parentNode.removeChild(el);
> });
>
Where supported, though top level generics such as Array.slice are not
standard, so:

var divList = document.getElementsByTagName('div');
Array.prototype.slice.call( divList );

Elsewhere:
https://mail.mozilla.org/pipermail/es-discuss/2009-December/010241.html

Received on Saturday, 24 April 2010 23:35:08 UTC