- From: Jonas Sicking <jonas@sicking.cc>
- Date: Wed, 4 Aug 2010 14:40:54 -0700
On Wed, Aug 4, 2010 at 11:10 AM, Alex Russell <slightlyoff at google.com> wrote: > Sorry for the lagged response, > > On Fri, Jul 30, 2010 at 2:56 PM, Oliver Hunt <oliver at apple.com> wrote: >> >> On Jul 30, 2010, at 2:46 PM, Alex Russell wrote: >> >>> On Fri, Jul 30, 2010 at 4:18 AM, Jonas Sicking <jonas at sicking.cc> wrote: >>>> On Thu, Jul 29, 2010 at 5:45 PM, Ian Hickson <ian at 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. >>> >>> Wait...what? Shouldn't some sort of NodeList be mutable? And shouldn't >>> JS support immutable Arrays? We need to fix both of these APIs, and we >>> keep heaping back-pressure on JavaScript's Array without any >>> reasonable resolution because we're not exploring how to make Array >>> subtypes work as we want them to for all the use cases (like this) >>> that we care to express. >> >> What would you expect a mutable NodeList to be? > > A good example would be the result of document.querySelectorAll(). Why couldn't querySelectorAll return a normal Array? / Jonas
Received on Wednesday, 4 August 2010 14:40:54 UTC