Proxy 是 JavaScript 的元编程工具,通过代理层拦截对象操作而不修改原对象;需传入目标对象和含 trap 的处理器,配合 Reflect 保持原生语义,但仅代理一层且不可序列化。

Proxy 是 JavaScript 提供的元编程工具,能让你在访问、修改、删除对象属性时插入自定义逻辑。它不改造原对象,而是创建一个“代理层”,所有操作先经过这个层再落到目标对象上。
创建 Proxy 实例并拦截基本读写操作
Proxy 构造函数接收两个参数:目标对象(target)和处理器对象(handler)。handler 中定义各种 trap(陷阱),比如 get 拦截读取、set 拦截赋值。
常见用法示例:
- 用 get 实现默认值返回:当属性不存在时返回指定值,而不是
undefined - 用 set 做数据校验:比如只允许数字类型赋值给 age 字段
- 用 has 控制
in操作符行为,隐藏某些属性 - 用 deleteProperty 禁止删除关键字段
实现私有属性访问控制
JavaScript 没有真正的私有字段语法(虽然有 # 号私有字段,但 Proxy 可以更灵活地模拟)。你可以约定以下划线开头的属性为“私有”,然后在 handler 中拦截对它们的访问。
立即学习“Java免费学习笔记(深入)”;
例如:
- 在 get 中检查 key 是否以
_开头,是则抛错或返回空值 - 在 set 中同样拦截,防止外部篡改内部状态
- 配合 ownKeys 和 getOwnPropertyDescriptor,让
Object.keys()和for...in也看不到这些属性
用 Reflect 配合 Proxy 保持默认行为
在 trap 中不要直接操作 target,而应使用 Reflect 对应方法(如 Reflect.get(target, key, receiver))。这样能保证原型链、this 绑定等原生语义不被破坏。
例如:
-
settrap 中调用Reflect.set(target, key, value, receiver)而不是target[key] = value -
get中用Reflect.get,避免丢失 getter/setter 或 this 上下文 - 如果某个 trap 不想干预,直接 return Reflect.xxx(...) 即可保留原行为
注意陷阱与限制
Proxy 本身不可被枚举(Object.keys(proxy) 返回空数组),且不能被 JSON 序列化(JSON.stringify(proxy) 得到空对象)。若需兼容,应在 handler 中处理 toJSON 或提供 valueOf 方法。
另外:
- Proxy 只代理一层,嵌套对象需递归代理或按需代理
- 不能代理原始值(如字符串、数字),只能代理对象
- 一旦创建,无法关闭或撤销(ES2020 新增
Proxy.revocable()可解决)


















