set拦截器用于拦截属性赋值操作,接收target、property、value、receiver四参数;可实现数据类型校验(如number、string、boolean、date)和边界检查(如数值范围)。

set 拦截器的基本作用
Proxy 的 set 拦截器用于拦截对目标对象属性的赋值操作。只要用 = 赋值、Object.defineProperty(配合 writable: true)、解构再赋值等触发 [[Set]] 内部方法的操作,都会进入 set 钩子。它接收四个参数:target(原对象)、property(属性名)、value(待设的值)、receiver(代理对象本身,常用于处理原型链或 this 绑定)。
实现数据类型校验
在 set 中通过 typeof、Array.isArray()、value instanceof Date 等判断类型,并拒绝非法值。建议抛出明确错误,便于调试:
- 对 number 类型字段,拒绝
null、NaN、undefined和字符串数字(如"123"),除非显式允许转换 - 对 string 类型,可检查是否为原始字符串(
typeof value === 'string'),排除 String 对象实例 - 对 boolean,只接受
true或false,不自动转换"true"、1等 - 对 date 字段,推荐要求是有效 Date 实例且
!isNaN(date.getTime())
加入边界检查逻辑
类型合法后,进一步检查值是否在业务允许范围内。常见方式包括:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 数值类:用
value >= min && value 判断,例如年龄限制 <code>0 - 字符串长度:用
value.length校验,如用户名 2–20 个字符 - 枚举值:用
['pending', 'done', 'error'].includes(value)限定取值范围 - 正则匹配:邮箱、手机号等可用
/^[\w-]+@([\w-]+\.)+[\w-]{2,7}$/.test(value)
注意:边界规则建议集中定义(如用 schema 对象描述每个字段的 type/min/max/enum),避免逻辑散落在 set 内部。
完整可运行示例
以下是一个带类型 + 边界校验的用户对象代理:
const userSchema = {
name: { type: 'string', minLength: 2, maxLength: 20 },
age: { type: 'number', min: 0, max: 150 },
role: { type: 'string', enum: ['admin', 'user', 'guest'] }
};
const user = {};
const proxy = new Proxy(user, {
set(target, prop, value) {
const rule = userSchema[prop];
if (!rule) return false; // 不允许写入未声明字段
// 类型校验
switch (rule.type) {
case 'string':
if (typeof value !== 'string') throw new TypeError(`${prop} must be string`);
if (value.length rule.maxLength) {
throw new RangeError(`${prop} length must be between ${rule.minLength} and ${rule.maxLength}`);
}
break;
case 'number':
if (typeof value !== 'number' || isNaN(value)) throw new TypeError(`${prop} must be a valid number`);
if (value rule.max) {
throw new RangeError(`${prop} must be between ${rule.min} and ${rule.max}`);
}
break;
case 'string-enum':
if (!rule.enum.includes(value)) throw new TypeError(`${prop} must be one of [${rule.enum.join(', ')}]`);
break;
}
target[prop] = value;
return true;
}
});
// 使用
proxy.name = "Alice"; // ✅
proxy.age = 25; // ✅
proxy.role = "user"; // ✅
proxy.age = -5; // ❌ RangeError
proxy.name = "A"; // ❌ RangeError(太短)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










