Why does Array.from also take a mapFn?

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Jun 24 09:31:22 PDT 2013


On Jun 24, 2013, at 8:42 AM, Jason Orendorff wrote:

> According to the January 30 meeting notes, Array.from is getting
> optional map functionality.[1]
> 
> This is motivated by the following example:
> 
>    class V extends Array {
>        constructor(...args) {
>            super(...args);
>        }
>    }
> 
>    var v, m;
>    v = new V(1, 2, 3);
>    m = v.map(val => val * 2);
>    console.log( m instanceof V ); // false :(
> 
> Of course changing Array.from doesn't fix this; v.map() still returns
> an Array, same as before. And there was already an easy workaround:
>    m = V.from(v.map(val => val * 2));

The issues (and discussion) is more complex then the above indicates. 

The root issue concerns what should Array producing methods such as Map produce when used in an Array subclass. Should the result be an Array instance (as it currently is in ES5) or should it be a new instance of the subclass.  If the latter, how is the actual subclass determined.  Also experience form other languages suggests that whichever the default is, sometimes you want the other behavior and sometimes an comply different kind of result object is desired.

My recollection is that we first discussed that the existence of Array.from make this issue somewhat less important because, just as you point out, .from can be used in conjunction with anything that produces an Iterable such as V.from(v.map(val => val * 2))  

That led to further discision of that usage and we got into things like the last example:
// Turn an array of nodeNames into NodeList of nodes
NodeList.from( ["div"], node => document.createElement(node) );
The option map in Array.from really addressed two issues.  First, it allows a mapping to be applied to Iterable that are not Array subclasses and hence do not directly support map. Second, it directly supports the most common use case and avoids the creation of intermediate arrays that are produced if the instance side map method is used:

> 
> This workaround seems superior to the proposal, because it's more
> generally applicable. The same thing works for the results of
> .filter(), .concat(), etc. Something very similar works for Set:
> 
>    m = Set(v.map(...));
> 
> Clearly not every possible composition of two primitives needs to be a
> builtin function. Why this particular one?

see above.  Arrays and NodeLists were the focus of the discussion. 
> 
> Cheers,
> -j
> 
>  [1]: https://github.com/rwldrn/tc39-notes/blob/master/es6/2013-01/jan-30.md#revising-the-array-subclassing-kind-issue
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> 



More information about the es-discuss mailing list