Proxy's optional target
uhm, you might be slightly behind current specs ... these changed proxy quite a lot so that first argument is the target, and second argument is the behavior.
var myProxy = new Proxy(target, handler);
at least that's how Firefox implemented it right now :D
var target = {test:123}, proxy = new Proxy(target, { get: function ($target, key) { alert($target === target); // true return $target[key]; } }) ; alert(proxy.test); // 123
On Jan 14, 2013, at 9:32 PM, Dmitry Soshnikov wrote:
Hello,
Don't know whether it was mentioned/asked before (sorry if so), but just a note: probably it makes more sense making the target argument as optional and the second one in the Proxy constructor's API.
Proxy(handler[, target]):
- If target is undefined, let the target be new Object(); ...
In this case we'll cover (probably the most used) use-case of direct-proxies:
var p = new Proxy({ get: function(target, name, value) { ... } });
Although... Actually, never-mind, I just looked at it again, and it looks a bit weird having some first argument "target" w/o actually specifying the one at creation. So yeah, explicit target makes sense. I just wanted to exclude these use-cases:
var p = new Proxy({}, handler);
where this use-less empty "{}" will be to many in proxies' code.
P.S.: I know it's not gonna happen, but in an "imaginary" world:
Anyways, if the explicit target, then it would be good refer it as this
value instead of explicit parameter. But in this case we cannot get reference to the handler object (currently this
refers to the handler object). But. Since proxies provide some internal meta-level API handling, we can refer the handler's method as private symbols instead. E.g.:
var p = new Proxy({ @get: function (name, value) { if (this. at getOwnPropertyDescriptor(...)) { this[name] = value; } } });
this
refers to the target, but this. at getOwnPropertyDescriptor(...) to the function of the handler object. But this is only at implementation level, from the end-level user's perspective, it looks like this
is the target and this. at getOwnPropertyDescriptor(...)
is the internal method hook on exactly the same target.
In this case, optional target becomes completely implicit and can be treated as just a "traceable" object.
This doesn't reflect some invariants as p === this
, if p is the proxy and this
is the target (and this is why p.name = 10; triggers the handler and this.name = 10; inside the handler function does not), so, just thinking saying.
Dmitry
On Jan 14, 2013, at 9:51 PM, Andrea Giammarchi wrote:
uhm, you might be slightly behind current specs ... these changed proxy quite a lot so that first argument is the target, and second argument is the behavior.
var myProxy = new Proxy(target, handler);
Oh, I'm aware about current pre-spec MDC article and API. And this is why saying. In most use-cases you probably wanna proxy an empty object, and this is why in current API you end up in code like this:
var p = new Proxy({}, handler);
And I'm saying about these "{}" always as the first argument.
Dmitry
and this
is the handler, not the target ...
var handler, target = {test:123}, proxy = new Proxy(target, handler = { get: function ($target, key) { alert($target === target); // true alert(this === handler); // true return $target[key]; } }) ; alert(proxy.test); // 123
and no, I don;'t think everyone gonna proxy empty objects but if that's the case you want that because either you are looking for a singleton, otherwise what's the point to have same target per each new handler? Your concern is the othr way round too, isn't it?
If you use new Proxy you want a different target, I guess, otherwise you are most likely looking for same handler, different targets, which makes more sense, imho
new Proxy({/fresh new target/}, sameHandler)
The proxy target is important because it specifies some invariants about the proxy (typeof, builtin brand, behavior of forwarding for unspecified traps, values of internal properties like [[DateValue]], [[NumberValue]], etc.).
On Jan 14, 2013, at 10:40 PM, Brandon Benvie wrote:
The proxy target is important because it specifies some invariants about the proxy (typeof, builtin brand, behavior of forwarding for unspecified traps, values of internal properties like [[DateValue]], [[NumberValue]], etc.).
Sure, but the target still exists. I't just created implicitly (as new Object()) if not provided.
- Explicit target:
var p = new Proxy(handler, {x: 10});
- Implicit target:
var p = new Proxy(handler); // which is the same as:
var p = new Proxy(handler, {});
Then only difference from the current API, that the target is the second argument to the Proxy constructor which allows to ditch cases like: var p = new Proxy({}, handler), where you're forced always pass this empty object.
But, here can be the trade-off, having this target as the first argument, because it correlates with the methods from ES5 like var o = Object.defineProperties({}, descriptors);.
Dmitry
yep, same as asking for defineProperties with properties definition used as "class" as unique required argument, it might make sense, but it's ok in any case as it is
Le 15/01/2013 06:53, Dmitry Soshnikov a écrit :
On Jan 14, 2013, at 9:32 PM, Dmitry Soshnikov wrote:
Hello,
Don't know whether it was mentioned/asked before (sorry if so), but just a note: probably it makes more sense making the target argument as optional and the second one in the Proxy constructor's API.
Proxy(handler[, target]):
- If target is undefined, let the target be new Object(); ...
In this case we'll cover (probably the most used) use-case of direct-proxies:
var p = new Proxy({ get: function(target, name, value) { ... } });
Although... Actually, never-mind, I just looked at it again, and it looks a bit weird having some first argument "target" w/o actually specifying the one at creation. So yeah, explicit target makes sense. I just wanted to exclude these use-cases:
var p = new Proxy({}, handler);
where this use-less empty "{}" will be to many in proxies' code.
Just to clarify a point. It is not entirely useless. It's used for invariant checks and as storage back-end, obviously.
On Jan 15, 2013, at 12:54 AM, David Bruant wrote:
Le 15/01/2013 06:53, Dmitry Soshnikov a écrit :
On Jan 14, 2013, at 9:32 PM, Dmitry Soshnikov wrote:
Hello,
Don't know whether it was mentioned/asked before (sorry if so), but just a note: probably it makes more sense making the target argument as optional and the second one in the Proxy constructor's API.
Proxy(handler[, target]):
- If target is undefined, let the target be new Object(); ...
In this case we'll cover (probably the most used) use-case of direct-proxies:
var p = new Proxy({ get: function(target, name, value) { ... } });
Although... Actually, never-mind, I just looked at it again, and it looks a bit weird having some first argument "target" w/o actually specifying the one at creation. So yeah, explicit target makes sense. I just wanted to exclude these use-cases:
var p = new Proxy({}, handler);
where this use-less empty "{}" will be to many in proxies' code. Just to clarify a point. It is not entirely useless. It's used for invariant checks and as storage back-end, obviously.
Sure, and it (the target) still would be there, just created implicitly. All the invariants are kept, the storage (the implicit target) is kept.
But, that's mentioned, if the target is implicit, then handler functions look a bit weird when receive it as the first argument.
Dmitry
2013/1/15 Dmitry Soshnikov <dmitry.soshnikov at gmail.com>
Sure, and it (the target) still would be there, just created implicitly. All the invariants are kept, the storage (the implicit target) is kept.
But, that's mentioned, if the target is implicit, then handler functions look a bit weird when receive it as the first argument.
I see your point, but would argue to always have the target be created explicitly. Implicitly creating objects behind the programmer's back just feels awkward, especially if this object is then exposed to handler functions as first argument (as you note).
Put another way, writing new Proxy({} , handler) more explicitly alerts the reader about what's going on.
Hello,
Don't know whether it was mentioned/asked before (sorry if so), but just a note: probably it makes more sense making the target argument as optional and the second one in the Proxy constructor's API.
Proxy(handler[, target]):
In this case we'll cover (probably the most used) use-case of direct-proxies:
var p = new Proxy({ get: function(target, name, value) { ... } });
Thanks, Dmitry