Le 27/05/2011 04:13, Mark S. Miller a écrit :
On Thu, May 26, 2011 at 5:04 PM, Cormac Flanagan <[email protected]
<mailto:[email protected]>> wrote:
[documenting/expanding some ideas briefly discussed at today's
meeting]
The current proxy proposal has a method to create a new proxy:
var proxy = Proxy.create(handler, proto);
We could extend this proposal to allow an existing object to be
converted to a proxy, via:
var proxy = Proxy.createFrom(object, handler, proto);
I am surprised by this proposal since a design goal of proxies was to
not be able to turn existing objects into proxies.
4th "driving force" of the proxy proposal:
"security: avoid enabling arbitrary ES objects to be able to intercept
the properties of another object"
The API itself (Proxy.create, Proxy.createFunction) seems to have been
design with this in mind.
Here, the return value 'proxy' is the same address as the argument
'object'.
The original object thus becomes a proxy. Any state of the
original object
is discarded.
The notion of object "state" is not defined anywhere in the ES5 spec.
What is your definition of an "object state" ?
This extension appears to support additional applications, such as
registering an observer on an existing object. The target object would
first be cloned, then the target object would be converted into a
proxy that
dispatches to the cloned object, but which also notifies observers
about
accesses/updates to the (now proxified) object.
Is this the only use case?
If so, would it rather make sense to provide a specific Object event API
for existing objects? It would allow to observe accesses/updates without
turning the object into a proxy with arbitrary handler methods.
There are a number of open issues relating to security etc:
In particular, what objects can be proxified in this way - perhaps not
frozen object,
or objects with non-configurable properties or with unique names.
In today's meeting, I made two suggestions along these lines:
* Given the current proxy semantics, we should allow this only if the
object-to-be-proxified is extensible and has no non-configurable own
properties.
* We have on occasion discussed modifying the proxy proposal so that
individual properties could be fixed rather than just the proxy as a
whole. (Note: I am not in favor of such a change, but it could be done
soundly.) Given that this change to proxies were done, then we should
allow proxification only if the object-to-be-proxified is extensible,
period.
In both cases, as you state, one effect of the operation is to remove
all configurable own properties from the object. In both cases, we can
adopt the rationale that the object-to-be-proxified could not have
taken any action inconsistent with it always having been a proxy.
In both cases, we need the further restriction that it is a kind of
object that can be emulated by a proxy. Today, this is technically
only objects of [[Class]] "Object" or "Function", but we're talking
about relaxing that in any case.
A design goal is that for any object that could be proxified,
we can replace it with a proxy in a way that is semantically
transparent.
If you provide the ability to put any functions in the handler object,
there in no such thing as "semantically transparent". The handler
methods can do whatever they wants; they are functions. Moreover with an
API like Proxy.createFrom(object, handler, proto), the handler methods
would need some help to initialize their internal proxy state in order
to align with the object passed as argument.
Maybe that what you were suggesting was to use a forwarding handler by
default as handler and to put the handler argument as "this.target"?
Even in this case, if creating proxies, an external user of the same
object has no guarantee whatsoever of seeing no semantic difference
since, for instance, any handler trap could throw an error when called.
My very first (mis)understanding of proxies was that they were an object
access/update event API and that the handler functions were nice event
handler. They are not. They are much more powerful. They are not an
/addition/ to regular internal object methods. They are a /replacement/
of it.
However, I agree that an object event API is a valid use case (I have
actually had a need for that a couple of days ago), but I don't think it
should be a proxy extension. In my opinion, it should be its own
library/API. Maybe implementable/standardizable with proxies + "become"
internal function (see slide 56 at [1]), but its own thing.
I would be much more in favor of something like:
----
Object.observe(o, observers);
----
Observers would be an object that looks like a proxy handler called on
every object interactions, but wouldn't be able to interact with the
object internal methods. It would just be an addition to internal
methods rather than a replacement as it's the case with proxies.
There wouldn't be any restriction based on property attributes
(enumerable, configurable, get, set...) or extensibility.
One question to discuss is to know if they should be called before or
after (or one observer method for each?) internal calls.
Of course, if there is another use case than object access/update
events, maybe that turning existing objects into proxies is a good idea,
but if there isn't, I think that a specific API may be safer.
David
[1] http://www.slideshare.net/BrendanEich/metaprog-5303821?from=ss_embed
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss