Closed Bug 658266 Opened 15 years ago Closed 13 years ago

[Harmony]Proxy: 'this' in getter/setter doesn't indicate the proxy object

Categories

(Core :: JavaScript Engine, defect)

x86
Windows XP
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: teramako, Unassigned)

References

Details

(Whiteboard: js-triage-needed)

User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0a1) Gecko/20110518 Firefox/6.0a1 Build Identifier: Mozilla/5.0 (Windows NT 5.1; rv:6.0a1) Gecko/20110518 Firefox/6.0a1 I noticed that 'this' in a normal method (getGreeting) indicates the created proxy object, but 'this' in getter/setter indicates the original object. Is this expected result ? var o = { name: "foo", getGreeting: function(){ console.log("getGreeting: ", this === o, this === p); // result: false true return "Hello, " + this.name; }, get greeting () { console.log("getGreeting: ", this === o, this === p); // result: true false return "Hello, " + this.name; }, }; var handler = { target: o, get: function (_, name) { console.log("[Handler]Getting:", name); return this.target[name]; } }; var p = Proxy.create(handler); console.info("p,getGreeting()") p.getGreeting(); console.info("p.greeting"); p.greeting; Reproducible: Always Actual Results:
Whiteboard: js-triage-needed
No longer blocks: harmony:proxy
This is not a bug, but expected behavior. The reason is that in the "get" trap, in the case of the accessor, |return this.target[name]| will trigger the accessor on |this.target| with |this| bound to the target, as it should. In the case of the method, |this.target[name]| returns a function, which is then called with |this| bound to the proxy. To write proxies that leave |this| in accessors bound to the proxy, you should make use of the third argument passed into the "get" trap: get: function(target, name, receiver) { console.log("[Handler]Getting:", name); return Reflect.get(target, name, receiver); } The |receiver| argument refers to the proxy itself. The |Reflect.get(target,name,receiver)| method basically does the same as |this.target[name]|, except that if target.name is an accessor, it will call the accessor with |this| bound to |receiver|. To my knowledge, the Reflect object does not yet exist in current implementations (it will be provided as a module in ECMAScript 6). But it can be implemented in JavaScript today. For an example implementation, see: <https://github.com/tvcutsem/harmony-reflect/blob/master/reflect.js#L1489> If you are only interested in the code implementing Reflect.get, look at <https://github.com/tvcutsem/harmony-reflect/blob/master/reflect.js#L1604> (you only need lines 1604-1620).
Status: UNCONFIRMED → RESOLVED
Closed: 13 years ago
Resolution: --- → INVALID
(In reply to Tom Van Cutsem from comment #1) I get it. Thank you very much :)
You need to log in before you can comment on or make changes to this bug.