archives

« Bugzilla Issues Index

#4147 — 22.1.3.1 Array.concat: isConcatSpreadable should use iterator if possible


@@isConcatSpreadable's name implies that it is semantically similar to the spread operator, which uses the spread source's iterator. However, Array.prototype.concat, when invoking the @@isConcatSpreadable algorithm, always does a manual numeric property read from the source.

I propose that the behaviour of Array.prototype.concat with respect to @@isConcatSpreadable should be aligned with Array.from - if no iterator is present on the source, then the current algorithm is used, but if the iterator is available, then it is used instead.

As far as I know, @@isConcatSpreadable only exists for back-compat purposes, and there's no compatibility issues with Array, as Array.prototype[@@iterator] behaves the same as the current algorithm.

...

Alternatively, some may argue that setting @@isConcatSpreadable on a bare array-like object with no iterator might as well be unsupported, since relying on @@isConcatSpreadable instead of spreads is dubious, and the difficulties that arise can be alleviated by setting the object's iterator to Array.prototype[@@iterator]. If this sounds more appealing, then the .concat behaviour should instead be aligned with the spread operator - in which case no array-like manual property read shall occur at all, instead resulting in a TypeError.

[Original discussion](https://twitter.com/webbedspace/status/574721788946464768).


ES6 didn't update any of the existing array methods to use iterators instead of (or as an alternative to) direct indexed accesses. concat is just one of those existing methods and I don't think it would make sense at this point to consider treating it differently from the other legacy Array methods.

Array.from is a completely new method in ES6 so it followed new rules.

You might consider proposing for ES7 that all the Array methods should be be adapted to work with Iterables.


(In reply to Allen Wirfs-Brock from comment #1)
> ES6 didn't update any of the existing array methods to use iterators instead
> of (or as an alternative to) direct indexed accesses. concat is just one of
> those existing methods and I don't think it would make sense at this point
> to consider treating it differently from the other legacy Array methods.
>
> Array.from is a completely new method in ES6 so it followed new rules.
>
> You might consider proposing for ES7 that all the Array methods should be be
> adapted to work with Iterables.

My main motivation for proposing this was to make it possible to attach Symbol.isConcatSpreadable to subclasses of sets, generator functions' prototypes, etc. and have it work "as expected". Not saying that's at all useful when compared to just using the "real" spread operator, merely that it's more intuitive in contrast to the present behaviour. Deferring(?) this to ES7 may result in a compatibility issue (but, the likelihood of people actually using Symbol.isConcatSpreadable for non-legacy purposes seems low, so I guess, in the field of back-compat bets, this would be surer than most).