proxy 可通过 set 拦截赋值实现类型/范围校验,get 拦截读取提供默认值或格式化,结合 reflect.set/get 保证透明转发与 setter 正确触发,并可封装为支持配置化规则的校验代理工厂。

Proxy 可以在属性读写时动态拦截并校验,核心是用 set 拦截赋值、get 拦截读取,配合自定义规则实现运行时校验。
用 set 拦截赋值并校验类型/范围
在 set 中判断目标属性是否符合预期(如必须为字符串、数字在指定区间、不能为空等),不符合就抛错或静默处理。
- 接收四个参数:
target(原对象)、property(属性名)、value(待设值)、receiver(代理对象本身) - 校验失败时返回
false(严格模式下会报TypeError)或直接throw new Error() - 记得最后返回
true表示设置成功,否则赋值会被忽略
例如限制 age 必须是 0–150 的整数:
const person = {};
const proxy = new Proxy(person, {
set(target, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value) || value 150) {
throw new TypeError('age must be an integer between 0 and 150');
}
}
target[prop] = value;
return true;
}
});
proxy.age = 25; // ✅
proxy.age = -5; // ❌ 抛错
用 get 拦截读取并做默认值/格式化
get 不直接参与“校验”,但可用于增强健壮性:比如访问未定义属性时返回默认值,或对敏感字段做脱敏处理。
- 避免因读取 undefined 导致后续逻辑出错
- 可统一转换输出(如把 date 字符串转为 Date 实例)
- 注意不要在
get中修改原对象,否则可能引发无限递归(如target[prop] = ...)
例如给缺失属性补空字符串:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
const data = { name: 'Alice' };
const safeProxy = new Proxy(data, {
get(target, prop) {
return prop in target ? target[prop] : '';
}
});
console.log(safeProxy.age); // '' 而不是 undefined
结合 Reflect 实现透明转发 + 校验增强
推荐在拦截器中用 Reflect.set() 和 Reflect.get() 替代直接操作 target,语义更清晰且能正确处理原型链、setter 等边界情况。
-
Reflect.set(target, prop, value, receiver)返回布尔值,比直接赋值更可控 - 校验通过后再调用
Reflect.set,失败则不触发原始行为 - 尤其在代理有 setter 的对象时,
Reflect.set会正确触发 setter;而target[prop] = value会绕过
示例(带 setter 的对象):
const obj = {
set price(v) {
console.log('setter triggered');
this._price = v;
}
};
const proxy = new Proxy(obj, {
set(target, prop, value) {
if (prop === 'price' && typeof value !== 'number') {
throw new Error('price must be a number');
}
return Reflect.set(target, prop, value);
}
});
proxy.price = 99.9; // ✅ 输出 "setter triggered"
封装成可复用的校验代理工厂
把校验规则抽离为配置对象,让 Proxy 创建逻辑可复用。每个属性对应一个校验函数,支持必填、类型、正则、自定义函数等。
- 规则配置结构清晰,比如
{ name: { required: true, type: 'string' }, age: { min: 0, max: 150 } } - 校验函数返回
true或错误信息,便于统一提示 - 代理内部只负责调度,不耦合业务规则
简单工厂示意:
function createValidator(target, rules) {
return new Proxy(target, {
set(target, prop, value) {
const rule = rules[prop];
if (rule) {
const isValid = typeof rule === 'function'
? rule(value)
: validateByRule(value, rule);
if (!isValid) {
throw new Error(`Invalid value for ${prop}`);
}
}
return Reflect.set(target, prop, value);
}
});
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










