On Nov 13, 2014, at 1:35 PM, Tom Van Cutsem wrote:
> 2014-11-13 20:31 GMT+01:00 Allen Wirfs-Brock <[email protected]>:
>
> 3) Proxies. Should Array.isArray treat proxy instances specially? To answer
> this question we need to think about what a ES programmer actually thinks
> Array.isArray means? The meaning that ES5 established is that Array.isArray
> returning true means that the object observably maintains the array `length`
> invariant.
>
> Is the `length` invariant really the dominant meaning JS developers attribute
> to Array.isArray? I think to most developers Array.isArray(obj) returning
> true means that it's safe to call the array utilities (map, forEach, ...) on
> obj, not so much that obj.length is special.
I agree that what JS programs think Array.isArray means is the key issue here.
But if "safe to call array utilities" is what it means then the world is really
confused. I guess it may come down to what "safe" means in that statement.
More than any other built-in class the Array prototype methods are specified to
be generic to any object.
All of the Array.prototype methods work just fine with `a` defined as:
```js
var a={0:"zero", 1:"one", length: 2};
```
but `Array.isArray(a)` answers false.
Conversely:
```js
var b=Object.freeze(["zero", "one"]);
b.sort();
```
is going to throw, even though `Array.isArray(b)` answers true.
>
> My intuition is that Array.isArray is often used to branch based on whether
> code received just one versus a collection of values. E.g. a function may
> take a single parameter that can be bound to either a single value or a
> collection of values, and treat a collection of values differently. In fact,
> that is essentially what Array.prototype.concat does: if the argument is an
> array, splice its values, otherwise, don't splice. This has nothing to do
> with `length` magic. The same goes for JSON.stringify (serialize as "[]" vs
> "{}").
Well, Array.isArray was new in ES5 so it's legacy only goes back that far.
We might redefine Array.isArray to be based upon testing for
@@isConcatSpreadable but that potentially would give different results for
legacy uses that did __proto__ hacking such as I mentioned in my previous mote.
>
> Now, if we take the meaning of Array.isArray to be "supports the
> Array.prototype utility methods", a proxy-for-array may of course expose a
> totally different API, leading a client that expects to be able to use the
> Array.prototype methods to fail. But this foregoes the fact that for
> virtually all practical use cases of proxies, proxy authors will not do this.
> They want to be able to wrap objects, intercept some things, but mostly
> faithfully forward those operations to the wrapped target. It would be rare
> for a proxy to change the API of the thing it wraps. Indeed, the whole point
> of proxies is to be able to intercept operations without modifying client
> code.
Certainly if you use a proxy to define a virtual object, to self-host,
spec-defined exotic objects or to implement DOM objects you just aren't
transparently wrapping the target object...
I think at the root of this is that many JS programmer don't really understand
what is (or isn't special about Array instances and that Array.isArray may have
just added to the confusion.
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss