Advanced JavaScript PatternsLesson 6.4
Proxy and Reflect: intercepting JavaScript object operations
Proxy constructor, handler traps, get set has deleteProperty, Reflect API, use cases validation reactivity logging, Proxy vs Object.defineProperty, revocable proxies
Intercept Any Object Operation
A Proxy wraps an object and intercepts fundamental operations — property reads, writes, deletions, and function calls — letting you add behavior transparently without modifying the original object. Vue 3's reactivity system is built on Proxy. Many validation and logging libraries use it too.
Basic Proxy with get and set Traps
const target = { name: "Ana", age: 28 };
const proxy = new Proxy(target, {
get(obj, key) {
console.log(`Reading: ${key}`);
return Reflect.get(obj, key);
},
set(obj, key, value) {
if (key === "age" && typeof value !== "number") {
throw new TypeError("age must be a number");
}
return Reflect.set(obj, key, value);
}
});
proxy.name; // logs "Reading: name", returns "Ana"
proxy.age = "x"; // throws TypeError
proxy.age = 30; // sets age to 30
Validation Proxy Factory
function validated(obj, schema) {
return new Proxy(obj, {
set(target, key, value) {
if (schema[key] && !schema[key](value)) {
throw new Error(`Invalid value for ${key}: ${value}`);
}
return Reflect.set(target, key, value);
}
});
}
const user = validated({}, {
age: v => typeof v === "number" && v >= 0
});
user.age = 25; // ok
user.age = -1; // throws Error
Why Reflect
Always use Reflect methods inside traps rather than accessing the target directly. Reflect.get(obj, key, receiver) correctly threads the receiver through inherited getters, preventing subtle bugs when prototypes are involved.
