patternjavascriptModeratepending
JavaScript Proxy for validation and change tracking
Viewed 0 times
proxyhandlertrapmetaprogrammingreactivevalidation
Problem
Need to intercept property access, assignment, or deletion on objects for validation, logging, or reactivity.
Solution
JavaScript Proxy patterns:
// Validation proxy
const schema = {
name: (v) => typeof v === 'string' && v.length > 0,
age: (v) => typeof v === 'number' && v >= 0 && v <= 150,
email: (v) => typeof v === 'string' && v.includes('@'),
};
function validated(obj, schema) {
return new Proxy(obj, {
set(target, prop, value) {
if (schema[prop] && !schema[prop](value)) {
throw new TypeError(`Invalid ${prop}: ${value}`);
}
target[prop] = value;
return true;
},
});
}
const user = validated({}, schema);
user.name = 'Alice'; // OK
user.age = -5; // TypeError: Invalid age: -5
// Change tracking proxy
function trackChanges(obj) {
const changes = [];
const proxy = new Proxy(obj, {
set(target, prop, value) {
const old = target[prop];
if (old !== value) {
changes.push({ prop, old, new: value, time: Date.now() });
}
target[prop] = value;
return true;
},
});
proxy.getChanges = () => [...changes];
return proxy;
}
const config = trackChanges({ debug: false, port: 3000 });
config.port = 8080;
config.debug = true;
config.getChanges();
// [{prop:'port', old:3000, new:8080, ...}, ...]
// Default values proxy
function withDefaults(defaults) {
return new Proxy(defaults, {
get(target, prop) {
return prop in target ? target[prop] : defaults[prop];
},
});
}
// Negative array indexing (Python-style)
function negativeIndex(arr) {
return new Proxy(arr, {
get(target, prop) {
const index = Number(prop);
if (Number.isInteger(index) && index < 0) {
return target[target.length + index];
}
return target[prop];
},
});
}
const a = negativeIndex([1, 2, 3, 4, 5]);
a[-1]; // 5
a[-2]; // 4Why
Proxy intercepts fundamental operations on objects. It's the mechanism behind Vue.js reactivity, MobX observables, and Immer's produce function.
Context
JavaScript metaprogramming and object interception
Revisions (0)
No revisions yet.