what is a receiver in JavaScript?
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:
receiver
Optional
The value ofthis
provided 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.
The receiver is the object in which the property lookup happens.
So yes, if you use a.jump
, a
is the receiver.
The concept is only relevant when you can execute arbitrary code when that property lookup happens. Basically, that means:
Accessor properties.
You can access the receiver by using
this
inside the getter or setter. The receiver will usually be the object in which you defined the property, or another object which inherits from it.var target = { get getReceiver() { return this; } }; target.getReceiver; // target var inherits = Object.create(target); inherits.getReceiver; // inherits
A built-in example is
__proto__
, defined as a property ofObject.prototype
but expected to be got or set on other objects (receivers).Proxy objects
Proxy objects allow you to define
get
orset
traps, which run a function when you attempt to get or set any property to the proxy. The receiver is provided as an argument of that function. The receiver will usually the Proxy object itself, or an object which inherits from it.var proxy = new Proxy({}, { get: function(target, property, receiver) { return receiver; } }); proxy.getReceiver; // proxy var inherits = Object.create(proxy); inherits.getReceiver; // inherits
Note you can use Reflect.get
or Reflect.set
to specify arbitrary receivers:
Reflect.get(target, "getReceiver", arbitraryValue); // arbitraryValue ¹
Reflect.get(proxy, "getReceiver", arbitraryValue); // arbitraryValue
¹ If the getter was defined in non-strict mode, it will be Object(arbitraryValue)
.
The name "receiver" comes from the specification, see Object Internal Methods and Internal Slots
[[Get]] (propertyKey, Receiver) → any
Return the value of the property whose key is propertyKey from this object. If any ECMAScript code must be executed to retrieve the property value, Receiver is used as the this value when evaluating the code.
[[Set]] (propertyKey, value, Receiver) → Boolean
Set the value of the property whose key is propertyKey to value. If any ECMAScript code must be executed to set the property value, Receiver is used as the this value when evaluating the code. Returns true if the property value was set or false if it could not be set.