Proxy forwarding
A proxy logs, validates, or measures property reads and writes before delegating normal behavior.
JS Puzzles · Const
Reflect exposes function-based forms of interceptable object operations, with method names matching Proxy traps. It is commonly used in proxy handlers to forward the default operation after adding custom behavior.
Reflect provides function forms of JavaScript's interceptable object operations. Its methods correspond to Proxy traps, so a proxy handler can add behavior and then delegate the default operation to Reflect with the same arguments.
Reflect.method(target, ...arguments)Individual Reflect methods return the result of their corresponding object operation; for example, Reflect.get returns a property value and Reflect.set returns a success boolean.
const target = { value: 1 };
const proxy = new Proxy(target, {
get(object, property, receiver) {
console.log(`read: ${String(property)}`);
return Reflect.get(object, property, receiver);
},
set(object, property, value, receiver) {
console.log(`write: ${String(property)}`);
return Reflect.set(object, property, value, receiver);
}
});
console.log(proxy.value);
proxy.value = 2;
console.log(target.value);The proxy logs operations, while Reflect forwards each operation to the target using the trap's matching arguments.
A proxy logs, validates, or measures property reads and writes before delegating normal behavior.
Code needs property access, assignment, deletion, or construction through dynamically selected operations.
A proxy handler must preserve ordinary JavaScript semantics instead of reimplementing inheritance and accessors.
Reflect is a built-in object whose static methods invoke interceptable object internal methods. Each method corresponds to a Proxy handler method, such as Reflect.get for property reads and Reflect.set for writes.
Follow-up: How can a proxy preserve normal behavior after logging a property read? The get trap should call Reflect.get with the target, property key, and receiver.
Reflect.get(target, key) performs a property read as a function call, while Reflect.set(target, key, value) performs an assignment-like operation. Reflect.set returns a boolean indicating whether the update succeeded.
Follow-up: Why pass receiver to Reflect.get or Reflect.set? It preserves the receiver used by accessor lookup and assignment, which matters when inherited getters or setters are involved.
Reflect.construct(target, argumentsList) performs the constructor operation represented by new target(...argumentsList). Reflect.construct can also receive newTarget, allowing the constructed object's prototype relationship to use a different constructor.
Follow-up: What does newTarget change? It changes the constructor's new.target value and can make the resulting object an instance of newTarget rather than target.
ProxyReflect.getReflect.setReflect.deletePropertyReflect.constructObject internal methods