[whatwg] Adding ECMAScript 5 array extras to HTMLCollection
Ian Hickson
ian at hixie.ch
Thu Jul 29 17:45:40 PDT 2010
The e-mails quoted below consist of the salient points of this thread:
On Fri, 23 Apr 2010, David Bruant wrote:
>
> 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.
On Sun, 25 Apr 2010, J Z wrote:
>
> 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
> });
>
> // turning live collection into static array fixes this
> Array.slice(document.getElementsByTagName('div')).forEach(function(el) {
> el.parentNode.removeChild(el);
> });
On Sat, 24 Apr 2010, David Bruant wrote:
>
> 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.
On Mon, 26 Apr 2010, Erik Arvidsson wrote:
> On Sun, Apr 25, 2010 at 01:07, David Bruant wrote:
> > Le 25/04/2010 00:39, J Z a écrit :
> >>
> >> 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).
> >
> > How would destructive methods like `push` or `sort` behave? Would
> > `document.body.childNodes.push(document.createTextNode('foo'))` append
> > text node to a body element? Or would it be a noop?
> >
> > That is actually a very good point. It think that the behavior should
> > be exactly the same as "an equivalent without array methods". (this
> > point of my proposal would need to be made completly explicit for each
> > method)
>
> One way to solve this could be to split Array into two interfaces. One
> to be used with immutable array like objects and one to use to mutate
> objects. Then we could apply the immutable array like interface to
> NodeList and its related interfaces. The benefit of doing that is that
> NodeList.prototype.push would be undefined instead of failing when
> called.
On Mon, 26 Apr 2010, David Flanagan wrote:
>
> Rather that trying to make DOM collections feel like arrays, how about
> just giving them a toArray() method? This makes it clear that a
> collection is not an array, but clearly defines a way to obtain an
> array. Clever implementors might even be able to optimize common
> uses-cases using some kind of copy-on-write strategy so that toArray()
> doesn't involve memory allocation and copying.
>
> Of course, trying to teach programmers when they ought to call toArray()
> and when it is not necessary is another matter. Perhaps calling the
> method snapshot() and focusing on the live vs. static distinction
> instead of the fake array vs. true array distinction would invite less
> misuse.
>
> Or we can just leave the DOM as it is and get used to calling the
> equivalent of Prototype's $A() function.
Before changing something this substantial, I'd like to have implementor
feedback regarding what the best way to address this is:
- somehow make HTMLCollections and NodeLists inherit from Array?
- define a bunch of feature on HTMLCollections and NodeLists so that
they're like arrays?
- provide a toArray() method or equivalent?
- do nothing?
- something else?
--
Ian Hickson U+1047E )\._.,--....,'``. fL
http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,.
Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
More information about the whatwg
mailing list