Proxy and Reflect
Proxy and Reflect in JavaScript
Meta-programming, operation interception, validation, and reactive systems.
The VIP Celebrity and the Secret Service Detail
`Proxy` wraps an object and intercepts fundamental operations (property lookup, assignment, enumeration, function invocation). `Reflect` provides standard methods to forward intercepted actions to the target.
The Proxy Handler and Traps
`new Proxy(target, handler)`. The handler contains trap methods such as `get`, `set`, `has`, `deleteProperty`, and `apply` that intercept runtime operations.
The Reflect API Companion
`Reflect` has 13 methods matching the 13 Proxy traps with identical signatures, returning boolean success statuses and ensuring correct `this` receiver binding.
Building Reactive State (Vue 3 Model)
Trapping `get` records which UI component is reading the property (dependency tracking); trapping `set` triggers automatic UI re-renders.
Schema Validation at Runtime
Using the `set` trap to enforce data types, numeric ranges, or required properties before allowing modifications on the underlying target.
Creating a reactive validation proxy with Reflect:
const userAccount = { username: "alex", age: 25 };
const validatorProxy = new Proxy(userAccount, {
get(target, prop, receiver) {
console.log(`[AUDIT] Accessed property: "${String(prop)}"`);
return Reflect.get(target, prop, receiver);
},
set(target, prop, value, receiver) {
if (prop === "age") {
if (typeof value !== "number" || value < 0) {
throw new TypeError("Age must be a positive number");
}
}
console.log(`[AUDIT] Updated "${String(prop)}" to ${value}`);
return Reflect.set(target, prop, value, receiver);
}
});
console.log(validatorProxy.username);
validatorProxy.age = 26;
try {
validatorProxy.age = -5; // Throws TypeError
} catch (err) {
console.log("Validation blocked:", err.message);
}
[AUDIT] Accessed property: "username"
alex
[AUDIT] Updated "age" to 26
Validation blocked: Age must be a positive number
Forgetting to Return Boolean from set() Trap
The Risk: A `set` trap must return `true` on successful assignment. Returning `false` or `undefined` throws `TypeError: 'set' on proxy: trap returned falsish` in strict mode.
The Fix: Always return `Reflect.set(target, prop, value, receiver)`, which naturally returns a boolean.
- ✓ `new Proxy(target, handler)` intercepts fundamental object behaviors.
- ✓ `Reflect` provides the standard default implementation for each of the 13 proxy traps.
- ✓ Pass `receiver` to `Reflect.get/set` to preserve correct `this` in getters/setters.
- ✓ Core architecture of Vue 3 Reactivity, MobX, and Mocking libraries.
- ✓ Set traps MUST return `true` to signal successful mutation.