On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson <i...@hixie.ch> wrote: > > 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?
I don't think this makes sense given the immutability of NodeLists. > - provide a toArray() method or equivalent? I think this would make sense, though I think it's also worth supplying functions that apply array-like operations directly on the nodelist. To avoid the overhead of copying the data. > - do nothing? Given how often this comes up, I think it's worth addressing this. > - something else? John Resig has been working on something in this area. I don't know if that's ready to publish yet though. / Jonas