Re: toArray() method for array-like DOM list objects

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(). This argument is somewhat littering and potentially confusing thing that has nothing to do with toArray conversion itself. 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?".

>> što do something that slice function is not intended to
>
> The slice function is purposefully generic. šThat means it's intended to
> take any array-like as |this| and produce an array.

I mean that slice() function is intended to create a _slice_. Using it to convert array-like object to array of same length (not even narrowed slice of it) is, strictly speaking, more like a workaround than its intended use.

>> šand that purpose is no-so-clear from the script code.
>
> That's a reasonable complaint.
>
>> šThere was also information from jQuery developers (cannot find a link unfortunately) that this method works even slower that manual iterating item-by-item.
>
> 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 have seen no such bug reports from jquery developers (though there
> were recent changes to Spidermonkey's slice() implementation to make it
> much faster on nodelists, when someone else complained about it), so
> either it wasn't a big issue for them or they for some reason didn't
> decide to report it.
>
>> štoArray() would be much more clear, straightforward, and fast way to achieve exactly converting DOM list to Array.
>
> 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? Theoretically _all_ array-like objects that currently can be converted to Array using Array.prototype.slice.call() should have toArray() method. 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. 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.

> A much better API, if it could be done, would be an Array constructor
> taking an arraylike object... šBut that would need to be done in
> ECMAScript, of course.

Passing DOM list to Array constructor would probably be ambiguous since DOM list object itself can represent a single Array item, so we would probably be forced to introduce an additional constructor-argument that would make its use less easy/elegant than convenient and straightforward toArray() method that is similar to (and consistent with) toString() method that we already have for many objects.

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.

Received on Thursday, 22 December 2011 22:42:34 UTC