On this page
Proxy and Reflect
Proxy wraps an object and intercepts operations. Reflect provides methods that correspond to proxy traps — used as the default behavior inside handlers.
Basic Proxy
let target = { name: 'Alice', age: 25 };
let handler = {
get(obj, prop) {
console.log(`Getting ${prop}`);
return Reflect.get(obj, prop);
},
set(obj, prop, value) {
console.log(`Setting ${prop} to ${value}`);
return Reflect.set(obj, prop, value);
}
};
let proxy = new Proxy(target, handler);
proxy.name; // logs "Getting name"
proxy.age = 26; // logs "Setting age to 26"
Validation Proxy
function createValidatedUser(data) {
return new Proxy(data, {
set(obj, prop, value) {
if (prop === 'age' && (typeof value !== 'number' || value < 0)) {
throw new TypeError('Age must be a non-negative number');
}
return Reflect.set(obj, prop, value);
}
});
}
let user = createValidatedUser({ name: 'Bob', age: 30 });
user.age = 31; // OK
// user.age = -1; // TypeError
Default Values
let withDefaults = new Proxy({}, {
get(obj, prop) {
if (prop in obj) return obj[prop];
return `(default: ${prop})`;
}
});
console.log(withDefaults.foo); // '(default: foo)'
Negative Array Indices
let arr = new Proxy([1, 2, 3], {
get(target, prop) {
let index = Number(prop);
if (index < 0) {
index = target.length + index;
}
return target[index];
}
});
console.log(arr[-1]); // 3
Revocable Proxy
let { proxy, revoke } = Proxy.revocable({ secret: 42 }, {});
console.log(proxy.secret); // 42
revoke();
// proxy.secret; // TypeError: Cannot perform 'get' on proxy that has been revoked
Reflect Methods
| Method | Operation |
|---|---|
Reflect.get |
Read property |
Reflect.set |
Write property |
Reflect.has |
in operator |
Reflect.deleteProperty |
delete |
Reflect.apply |
Function call |
Reflect.construct |
new |
function greet(name) {
return `Hello, ${name}`;
}
Reflect.apply(greet, null, ['Alice']); // 'Hello, Alice'
Reactive Data (Vue 3 Concept)
Frameworks use Proxy for reactivity:
function reactive(obj, onChange) {
return new Proxy(obj, {
set(target, prop, value) {
const old = target[prop];
const result = Reflect.set(target, prop, value);
if (old !== value) onChange(prop, value);
return result;
}
});
}
let state = reactive({ count: 0 }, (prop, val) => {
console.log(`${prop} changed to ${val}`);
});
state.count = 1; // logs change
When to Use Proxy
- Validation and access control
- Logging and debugging
- Virtual objects (API wrappers)
- Reactive state systems
Avoid Proxy for simple cases — it adds overhead and can complicate debugging.