'What is a receiver in JavaScript?
I am reading You Don't Know JS: ES6 & Beyond and found some confused wording like:
We declare a
get(..)handler as a named method on the handler object (second argument toProxy(..)), which receives a reference to the target object (obj), the key property name ("a"), and the self/receiver/proxy (pobj).
My question is, what does "receiver" mean above and where does its name come from?
It seems like if I have an object "a" with a member function "jump":
var a = { jump: function() { console.log('jump!'); } };
If I run a.jump(); then "a" is the receiver.
Is that how it works?
For people who read the same book: when you come to the Proxy First, Proxy Last section, you can add one line in the code to get a more clear picture about the context in the "get" trap:
var handlers = {
get(target, key, context) {
console.log(greeter === context); //true, this line added
return function() {
context.speak(key + "!");
};
}
},
catchall = new Proxy({}, handlers),
var greeter = {
speak(who = "someone") {
console.log("hello", who);
}
};
// setup `greeter` to fall back to `catchall`
Object.setPrototypeOf(greeter, catchall);
greeter.speak(); // hello someone
greeter.speak("world"); // hello world
greeter.everyone(); // hello everyone!
As you can see, thanks to the naming of the third argument of the "get" trap above, "context", the receiver can vary according to lexical code -- greeter.everyone();. Please refer to Oriol's very detailed answer below for a better understanding.
Solution 1:[1]
I spent some time trying to figure out exactly what this "receiver" could and would be used for when used with Reflect.get, and, perhaps unsuprisingly, it's all just as MDN explains:
receiverOptional
The value ofthisprovided for the call to target if a getter is encountered. When used withProxy, it can be an object that inherits fromtarget.
Basically, as far as I could assess, the decisive role it plays with Reflect.get is when used to access getter properties. For instance, the Reflect.get call in the following snippet will return 2, and not undefined.
const obj = { get foo() { return this.bar; } };
Reflect.get(obj, "foo", { bar: 2 });
The actual getter (get foo()...) is invoked with { bar: 2 } as the "receiver". Without third argument to Reflect.get, the receiver is implied to be the object itself, naturally -- and since it does not have a bar property, undefined is returned. If it had defined a bar property, things are far simpler indeed:
const obj = { bar: 1, get foo() { return this.bar } };
obj.foo; /// evaluates to 1
Reflect.get(obj, "foo"); /// evaluates to 1, equivalent to above
Reflect.get(obj, "foo", { bar: "soap" }) /// evaluates to, guess what, "soap"
I don't think there is anything more than that to it, not with Reflect.get, anyway.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
