With ordinary objects, methods and property getter functions are both
invoked on the object itself. If this object is proxied with
Proxy.Handler, however, the property getter function will be invoked on
the original object and the method will be invoked on the proxy object.
The code below demonstrates.
I find this surprising, though I'm not sure whether it constitutes a bug
in Proxy.Handler. I do think it is at least a reason why the receiver
argument to get() is necessary and should not be removed as proposed by
http://wiki.ecmascript.org/doku.php?id=strawman:proxy_drop_receiver
The code that demonstrates this is below. It runs in the current
Firefox Aurora. I have actually been affected by this issue when the
proxy object is stored in a WeakMap but the object it is forwarding to
is not in the WeakMap.
David Flanagan
if (this.console) print = console.log.bind(console);
// An object with an accessor property and a method.
var o = {
get property() { return map.get(this); },
method: function() { return map.get(this); }
};
var map = new WeakMap();
map.set(o, "o");
// Both the getter function and method are invoked on o
print(o.property); // prints "o"
print(o.method()); // prints "o"
// This works for inherited properties and methods, too
var p = Object.create(o);
map.set(p, "p");
print(p.property); // prints "p"
print(p.method()); // ditto
// When we create a proxy with a forwarding handler, though, the this value
// is different in the two cases.
var handler = {
target: o,
get: function(receiver, name) {
return this.target[name]; // Same as Proxy.Handler.prototype.get
}
}
var q = Proxy.create(handler);
map.set(q, "q");
print(q.property); // Prints "o"
print(q.method()); // Prints "q"
// In order to invoke the getter function on the same object as the method
// we have to go to more trouble and use code that is probably much slower.
// And, we need that first receiver argument.
var handler2 = {
target: o,
get: function(receiver, name) {
var d = Object.getOwnPropertyDescriptor(this.target, name);
if (d.value) return d.value;
else return d.get.call(receiver);
}
};
var r = Proxy.create(handler2);
map.set(r, "r");
print(r.property); // Prints "r"
print(r.method()); // Prints "r"
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss