[whatwg] Adding ECMAScript 5 array extras to HTMLCollection
David Bruant
bruant at enseirb-matmeca.fr
Sat Apr 24 23:33:53 PDT 2010
Le 24/04/2010 22:50, J Z a écrit :
> On Fri, Apr 23, 2010 at 10:30 PM, David Bruant
> <bruant at enseirb-matmeca.fr <mailto: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++)
I think I can take your point as a "pro" more than a "con", because in
ES5, right before the definition of each array extra method, a paragraph
like the following can be found :
"The range of elements processed by forEach is set before the first call
to callbackfn. Elements which are appended to the array after the call
to forEach begins will not be visited by callbackfn. If existing elements of
the array are changed, their value as passed to callback will be the
value at the time forEach visits them; elements that are deleted after
the call to forEach begins and before being visited are not visited."
This point is confirmed by every algorithm where the length is "saved"
once for all before the loop and not got from the .length property each
time.
>
> 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;
>
> document.getElementsByTagName('div').forEach(function(el) {
> el.parentNode.removeChild(el); // doesn't work as expected
> });
This code doesn't work as expected as the following doesn't either :
var divs = document.getElementsByTagName('div');
for(var i=0, l = divs.length ; i < l ; i++){
var el = divs[i]; // Due to the live-ness, this might not work as
expected
el.parentNode.removeChild(el);
}
This code written as a for-loop behave exactly the same way (in this
case) as the .forEach one, so it's as buggy as the forEach one.
My point is that forEach doesn't create more bugs than before, which is
what you seem to imply.
Adding .forEach and other Array extras wouldn't prevent programmers to
remember that they are dealing with a live object even within a
.forEach, the same way they are not supposed to forget it with a for-loop.
I have thought a lot about weirdnesses that people could think about
like trying to assign a value to the HTMLCollection (divs[14] =
myOtherDiv), but once again, it wouldn't be more allowed than it
currently is (I have no idea of what happens today, but if an error is
thrown in a for-loop, it should throw an error as well in a call within
a forEach).
This has nothing to do with this thread, but
document.getElementsByTagName('div') should return a NodeList
(http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-A6C9094). Returning
an HTMLCollection is a Firefox bug
(https://bugzilla.mozilla.org/show_bug.cgi?id=14869).
>
> // turning live collection into static array fixes this
>
> Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
> el.parentNode.removeChild(el);
> });
I have not found anything about a Array.slice method and the ES5 .splice
method doesn't seem to by usable in the way you describe. What did you
mean ?
The idea of turning the live object into a static array seems to be an
interesting one for some cases, but once again a problem you could solve
with a for-loop (in a live object or not like the results of
querySelectorAll) can be solved with a .forEach.
On the other side, the equivalent for-loop (according to the ES5 spec)
of a buggy forEach will be buggy as well.
David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/whatwg-whatwg.org/attachments/20100424/9a2ab434/attachment.htm>
More information about the whatwg
mailing list