Proxy 代理不自动转发属性调用,需通过 handler 中的 trap 显式控制;推荐用 Reflect.get/set 等实现安全转发,确保原型链、getter/setter 和 this 正确;空 handler 会自动透传但无拦截能力;转发是单向的,直接操作 target 不触发 trap。

Proxy 代理对象本身不自动“转发”属性调用,而是通过 handler 中的 trap(陷阱)函数显式控制行为。所谓“转发”,本质是 handler 函数内部调用 Reflect 方法或直接操作 target,把操作委托给原始对象执行。
用 Reflect 实现安全、标准的转发
推荐在 get/set 等 trap 中使用 Reflect.get()、Reflect.set() 等,它们语义上与原生操作一致,能正确处理原型链、getter/setter 和 this 绑定。
-
Reflect.get(target, prop, receiver):比target[prop]更可靠,尤其在有 getter 或继承时 -
receiver参数必须传入(通常是 proxy 本身),确保方法内this指向正确 - 例如:
return Reflect.get(target, prop, receiver);就是最简、最标准的读取转发
手动转发时需注意的细节
如果不用 Reflect,而选择 target[prop] 或 target[prop] = value,容易出问题:
- 忽略原型链:直接访问可能跳过原型上的 getter
- this 指向错误:在调用方法时,
target.method()的this是 target,不是 proxy,可能破坏上下文 - 无法捕获不可写/不可配置属性的报错逻辑(Reflect 会如实抛出)
无拦截时的默认转发行为
如果 handler 是空对象({}),Proxy 仍会自动将所有操作透传给 target —— 这是 Proxy 的底层机制,不是代码写的逻辑,但这种“透明代理”不经过任何 trap,无法做日志、校验等增强。
- 例如:
const p = new Proxy({x: 1}, {}); p.x → 1;p.y = 2;console.log(p.y, p === p) → 2, true - 此时 target 和 proxy 数据同步,但没有任何中间控制
转发 ≠ 双向同步,而是单向代理层调用
Proxy 的转发只发生在通过 proxy 访问时;直接操作 target 不会触发 handler,也不会反向影响 proxy 的行为(除非 handler 显式监听 target 变化)。
- proxy.a = 10 → 触发 set trap → 可转发到 target
- target.a = 20 → 不触发任何 trap,proxy.a 也会变成 20(因为 proxy 读取时仍从 target 取值)
- 但若 handler 的 get 中做了缓存或计算,target 直接改值就可能绕过逻辑


















