Why does Array.from accept non-iterable arraylikes?

Brandon Benvie bbenvie at mozilla.com
Tue Jun 25 13:19:47 PDT 2013


On 6/25/2013 1:09 PM, Jason Orendorff wrote:
> On Tue, Jun 25, 2013 at 12:33 PM, Allen Wirfs-Brock
> <allen at wirfs-brock.com> wrote:
>> This design discussion really wasn't just about iterator.   In ES6 we have various property keys that are hooks deeply into either the semantics of core language features:  @@create, @@hasInstance, @@ToPrimitive, @@iterator, @@toStringTag, @@isRegExp.
>>
>> Anyone plugging into these hooks really should be intentional about what they are doing.  Accidentally  doing so my poor name choice may mot be disastrous but it is likely to be dificult to debug.   Using a symbol for these properties greatly reduces the likelihood of such an accident.
> This is indeed the counterargument. We should weigh this against the
> benefits of iterators being polyfillable.
>
> Let's take a concrete example. CKEditor 4 has a constructor named
> CKEDITOR.dom.iterator:
>    http://docs.ckeditor.com/#!/api/CKEDITOR.dom.iterator
>
> The full extent of trouble we can expect from this naming conflict is
> that if somone accidentally did
>
>      arr = Array.from(CKEDITOR.dom);
>
> the error message would say something like "iterator object has no
> .next() method" rather than "Object not iterable". The mistake seems
> unlikely in the first place, and the resulting error is actually no
> harder to debug.
>
>> We could make an exception for iterator, but why?  That just introduces an inconsistency in the design.
> I think I mentioned several reasons. But mainly, iteration is worth
> polyfilling, and making it polyfillable will put it in users' hands
> literally years before symbols become universally available.
>
> I don't think the inconsistency will even be all that unaesthetic. ES5
> and previous have protocols too, using plain old string property
> names: .length, .toString(), .valueOf(), and .prototype. One more is
> not so bad, if it's something important.
>
> -j
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

It's not just about backward compatibility, but also usability. 
Mandating the addition of a non-symbol property in order to work with a 
protocol (in this case the iterator protocol) is not good.

     var dict = Object.create(null);
     Object.defineProperty(dict, 'iterator', { value: function*(){ 
/*...*/ } })

It's `__proto__` all over again (looking at __proto__ as the "get/set 
[[Prototype]] protocol"). Just say no.


More information about the es-discuss mailing list