Proxy 与 Reflect 配合实现安全元编程:Proxy 拦截操作,Reflect 执行默认行为;Proxy 返回代理对象不修改原对象,需对象类型 target,handler 中未定义 trap 则透传;常用 trap 如 get/set/has 等应调用对应 Reflect 方法以正确处理 receiver 和原型链;Reflect 方法统一返回布尔值、避免抛错,优于直接操作或 Object API。

ES6 的 Proxy 和 Reflect 是一套配合使用的元编程工具:用 Proxy 拦截操作,用 Reflect 执行默认行为。关键不是单独用哪个,而是“拦截后如何安全地转发”——Reflect 方法正是为此设计的。
Proxy 基础:创建可拦截的对象包装器
Proxy 不修改原对象,而是返回一个新代理对象,所有对它的访问都会经过你定义的拦截逻辑:
-
语法固定:
const proxy = new Proxy(target, handler),其中target可以是普通对象、数组、函数甚至另一个Proxy;handler是配置拦截行为的对象。 -
无拦截即透传:如果
handler里没写某个 trap(比如没写get),对应操作会直接作用于target,不会报错也不会静默忽略。 -
不能代理原始值:
target必须是对象类型(null也不行),数字、字符串、布尔值需先转为包装对象(如new Number(42))才能代理。
常用拦截器(Traps)与对应 Reflect 方法
每个 trap 接收特定参数,推荐在拦截逻辑中调用对应的 Reflect.xxx() 来执行原始操作,它比直接操作 target 更可靠(比如正确处理 receiver 参数、保持原型链一致):
macOS 微信消息自动化工具。通过 GUI 自动化实现:发送消息给指定联系人、读取聊天内容、监控新消息。适用于需要自动化微信操作的场景,如定时发送、批量回复、消息备份等。依赖 peekaboo 进行屏幕截图和 UI 交互。仅支持 macOS。开源地址:https://github.com/chairmanmia...
-
get(target, prop, receiver):拦截读取,如proxy.name或proxy['age']。常用场景:设置默认值、日志记录、响应式依赖收集。应返回Reflect.get(target, prop, receiver)或自定义值。 -
set(target, prop, value, receiver):拦截赋值,如proxy.count = 5。必须返回布尔值表示是否成功。验证逻辑写在这里,再调用Reflect.set(target, prop, value, receiver)完成赋值。 -
has(target, prop):拦截prop in proxy。返回布尔值,可用于隐藏属性或模拟稀疏数组。 -
deleteProperty(target, prop):拦截delete proxy.prop。返回布尔值,适合实现只读属性保护。 -
ownKeys(target):拦截Object.keys(proxy)、for...in等枚举操作。必须返回数组,可用来过滤不可见属性。
Reflect 的核心作用:提供标准化的底层操作接口
Reflect 不是一个类,而是一组静态方法,名字和 Proxy traps 一一对应。它的价值在于:
立即学习“Java免费学习笔记(深入)”;
-
统一行为契约:比如
Reflect.set()总是返回布尔值,而直接target[prop] = value总是返回value,不利于拦截逻辑判断。 -
正确处理 receiver:在
get/set中,receiver是发起操作的对象(通常是proxy)。直接操作target会丢失它,但Reflect.get(target, prop, receiver)会确保 getter 内部的this正确指向receiver。 -
替代 Object API:多数
Reflect方法都有对应Object方法(如Reflect.definePropertyvsObject.defineProperty),但前者失败时返回false,后者抛错,更适合在拦截器中使用。
实用示例:带类型校验的用户对象
下面代码让 user.age 只接受数字且 ≥ 0,同时 user.name 自动转为字符串:
const user = { name: '', age: 0 };
const validatedUser = new Proxy(user, {
set(target, prop, value, receiver) {
if (prop === 'age') {
if (typeof value !== 'number' || value < 0) {
throw new TypeError('age must be a non-negative number');
}
} else if (prop === 'name') {
value = String(value);
}
return Reflect.set(target, prop, value, receiver);
},
get(target, prop, receiver) {
// 访问不存在属性时返回 undefined 而非报错
return prop in target ? Reflect.get(target, prop, receiver) : undefined;
}
});
validatedUser.age = 25; // ✅
validatedUser.name = 123; // ✅ 自动转为 "123"
validatedUser.age = -1; // ❌ 抛出 TypeError


















