- From: Boris Zbarsky <bzbarsky@MIT.EDU>
- Date: Thu, 22 Dec 2011 18:07:19 -0500
- To: "Marat Tanalin | tanalin.com" <mtanalin@yandex.ru>
- CC: www-dom@w3.org
On 12/22/11 5:41 PM, Marat Tanalin | tanalin.com wrote: > 22.12.2011, 23:05, "Boris Zbarsky"<bzbarsky@MIT.EDU>: >> On 12/22/11 1:51 PM, Marat Tanalin | tanalin.com wrote: >> >>> At least since it uses some function with dummy argument >> >> What dummy argument? > > I mean 0 (zero) -- second argument passed to Array.prototype.slice.call() and used as first and only argument for called slice(). You don't need that. Array.prototype.slice.call(nodelist) works fine, because |ToInteger(undefined) === 0|. See ECMA-262 section 15.4.4.10. > For example, people who don't [fully] understand how does this conversion method work could answer a question like "Why should this zero be passed to slice() function every time if it should be enough to pass just array-like object to convert itself?". See above. >> That would simply be an implementation bug. One which toArray may well >> share if it were implemented. > > Of course, performance depends on implementation. However I still tend to believe that indirect (with call()) calling a function (Array.prototype.slice()) with passing some arguments (DOM list object itself, and zero) to it should be quite probably slower than just direct calling a method for object (domList.toArray()) without arguments. I tend to be very skeptical of faith-based performance claims not backed up with measurement or profiling.... What toArray has to do in most UAs is to call from JS into C++, then using C++ APIs to the JS engine create an array, fill it with JS objects corresponding to the nodes, etc. What slice() has to do is to get the objects corresponding to the nodes out of the nodelist (which is already fast-pathed in UAs because web code does it) and then put them in an array object. Which one is faster in practice depends on the overhead of the APIs used for toArray above as compared to the JS-engine-internal APIs that can be used when creating the array via slice(), as well as on the relative cost of getting the right JS objects in both approaches. I won't even guess as to which of those is faster. I do think that if I were implementing toArray in Gecko, I would be likely to just reuse some of the slice() code. >> I'm almost willing to buy "clear" and "straightforward". Except that it >> would only work for some objects but not others, whereas slice() works >> for any array-like. So you'd have to know exactly what sort of object >> you have to use it; in practice this would be a huge pain I suspect. > > Could you provide an example of such object where slice() works, but toArray() would not? Sure. A JS array object. Or this object: { length: 2, 0: "a", 1: "b" } > Theoretically _all_ array-like objects that currently can be converted to Array using Array.prototype.slice.call() should have toArray() method. "array-like" in this context means "has a property named 'length'". > It would be enough to have this ability for DOMNodeList and DOMTokenList only, though. I doubt that inability to call toArray() for literally _any_ object could be an issue in real-world usecases. It would mean that code which currently uses Array.prototype.slice and can take as input either arrays or nodelists (common in JS libraries) would need to either keep using Array.prototype.slice or check what its argument is. > Each object type has its own API based on what's expected (and is documented on MDN in particular) from the specific objects, it's perfectly OK. I doubt you're really appreciate NodeList and HTMLCollection having different APIs, even if they were documented... > Passing DOM list to Array constructor would probably be ambiguous since DOM list object itself can represent a single Array item This ambiguity already exists for numbers, yes? Why is a separate argument not needed there, apart from the "it's always been that way" argument. > We could probably do something like Array.import(domList) instead, but it seams to be still questionable whether this would be really better than toArray() method applied directly to DOM list object itself. It would be better for cases when you're working with arbitrary arraylikes which may or may not be nodelists, for sure. -Boris
Received on Thursday, 22 December 2011 23:07:48 UTC