Le 29/07/2013 20:41, Allen Wirfs-Brock a écrit :
The legacy [[Class]] internal property conflated these two concepts. Sometimes
it was used for to ensure that a built-in method was operating upon an instance
that actually had the internal state or conformed to other implementation level
invariants needed by the method. Other times, [[Class]] was tested for basic
external behavioral classification purposes that don't really care at all about
implementation level object invariants.
In most cases, the ES6 spec. language such as "if O is an exotic X object" or "does
X have a [[XXX]] internal data property" works fine as a direct replacement of an ES5
[[Class]] test because there are a one-to-one correspond between a ES6 built-in that is represented
by specific kind of exotic object or that has a specific internal data property and with a ES5
built-in with the corresponding [[Class]] value.
Can all the [[Class]] replacement tests be passed by proxies in a way or
another so that a proxy can impersonate a given "class" of exotic
object? (most likely by having one of these objects as target)
Also, I fail to understand the difference between "if O is an exotic X
object" and "if O.[[Class]] === X".
If proxies for arrays do not pass such tests, some built-ins behave in
unexpected ways.
What's expected? Just because a proxy has an exotic array object as its target
doesn't mean that is functions as an exotic array.
This suggests that the opposite could be true, that is that a proxy with
any target might impersonates an array as long as it passes some tests.
I wonder how much of a good idea this is.
The (granted implicit) model of "a proxy for exotic object X is seen by
all algorithms as an exotic object X" feels simpler even if it means
that a proxy might not act as an internal algorithm expects.
In any case, regardless of how many tests a proxy passes, it has always
a way to wrongly behave after having passed the test.
Here's the list of relevant built-ins, based on searching the ES6 spec for "is an
exotic Array object":
* Object.prototype.toString
As currently spec'ed. toString will invoke the HasProperty(@@toStringTag) of the proxy and if the
result is true invoke the Get trap to retrieve the value used to construct the toString result. All
of the new built-ins have @@toStringTag methods. I considered adding them for the built--ins that
carry over from ES5. Then, if the @@toStringTag of Array.prototype is "Array" then
Object.prototype.toString(new Proxy([ ], { })) should return "[Object Array]".
Excellent.
It also means that any proxy that customizes its @@toStringTag could
have O.p.toString return "[Object Array]", right?
However, this would be a breaking change for existing code explicitly wires
their prototype chain to inherit from Array.prototype.
Saving existing code from proxies is a dead end in my opinion.
* Array.isArray
We've discussed the meaning of this in the past and have agreed that it should
be considered a test for exotic array-ness and in particular the length
invariant. A Proxy whose target is an exotic array may or may not qualify.
I don't really understand what you're testing here to checking the
length invariant.
Can a proxy be written to pass this test?
Can a proxy be written so that the value of this test changes over time?
* JSON.stringify
There are two distinct use cases of [[Class]]==Array in the ES5 spec of this function.
Both are currently in the ES6 spec. as exotic array tests. The first use case is to see
if the "replaceer" argument is an white-list array. This could be special
cased via a @@isJSONArray that would work through a proxy, but I dubious that the
additional complexity is justified.
Maybe a test on whether the value is iterable? (so that replacer can
also be a Set, etc.)
It's worth noting that I hit upon these issues because users of my
harmony-reflect shim, which are using direct proxies today in ES5, have
reported them (see [1],[2]). This adds some evidence that users expect the
above built-ins to behave transparently w.r.t. proxies for their use cases. My
library patches some of these built-ins to recognize my own emulated proxies,
but this is just an ad hoc solution. ES6 users will obviously not be able to do
this.
They may expect this, but I don't see what generalizations we can make.
Whether a proxy over a built-in is behaviorally substitutable for the built-in
completely dependent upon the the definition of the specific proxy.
Again, this seems to suggest that a proxy could pretend to be a Date to
one algorithm, an Array to another and a RegExp to another. I'm not sure
what good comes out of that.
David
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss