proxy是javascript中用于拦截并自定义对象基本操作的元编程机制,通过new proxy(target, handler)创建代理,其中handler定义get、set等陷阱来控制属性读写,未拦截操作自动转发至target,修改同步生效。

Proxy 是 JavaScript 中用于拦截并自定义对象基本操作的元编程机制,不是网络代理,而是一个“行为代理层”,在目标对象和访问者之间插入控制逻辑。
Proxy 的核心结构:target + handler
创建 Proxy 必须传入两个参数:
- target:要被代理的原始对象(可以是普通对象、数组、函数,甚至 null);
- handler:一个配置对象,内部定义若干“陷阱”(traps),即对特定操作的拦截函数,如 get、set、has、apply 等。
未被 handler 显式拦截的操作会自动转发到 target,代理对象的修改也会同步反映在 target 上。
最常用的两个陷阱:get 和 set
它们分别控制属性读取和赋值行为,是构建响应式、校验、日志等功能的基础:
- get(target, prop, receiver):当访问 proxy.prop 时触发。可用于提供默认值、记录访问、实现链式嵌套代理(如 proxy.a.b.c);
- set(target, prop, value, receiver):当执行 proxy.prop = value 时触发。注意必须返回 true 才算赋值成功,否则严格模式下会抛出 TypeError;常用于类型校验、副作用触发(如更新 UI)。
示例中常配合 Reflect API 使用(如 Reflect.get / Reflect.set),确保默认行为不丢失且 receiver 正确传递。
其他实用陷阱简览
除 get/set 外,常见 trap 还包括:
- has:拦截 in 操作符(如 'x' in proxy);
- ownKeys:拦截 Object.keys()、Object.getOwnPropertyNames() 等枚举操作;
- deleteProperty:拦截 delete proxy.prop;
- apply:拦截函数调用(proxy()),适用于装饰函数;
- construct:拦截 new proxy(...),用于自定义构造逻辑。
每个 trap 都接收明确参数,设计时需注意 receiver 的语义(通常是 proxy 或其派生对象),避免 this 绑定异常。
使用限制与注意事项
Proxy 并非万能:
- 不能代理原始值(如字符串、数字、布尔值),只能代理对象类型;
- 代理对象与原对象不相等(proxy !== target),且 Object.is(proxy, target) 为 false;
- 性能开销略高于普通对象,高频场景需权衡;
- 无法拦截某些静态操作,如 Object.assign() 内部直接操作属性,不经过 proxy trap。
它不是 Object.defineProperty 的替代品,而是更底层、更全面的对象行为控制方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











