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

Reply via email to