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 of this provided for the call to target if a getter is encountered. When used with Proxy, it can be an object that inherits from target.

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 of Object.prototype but expected to be got or set on other objects (receivers).

  • Proxy objects

    Proxy objects allow you to define get or set 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.

Tags:

Javascript