receiver是维持proxy与原对象逻辑关联的关键桥梁,它在每个trap和reflect方法中精确传递调用上下文,确保getter/setter的this绑定、原型链查找及依赖收集准确无误。

Reflect 本身不“保持”关联,而是通过 receiver 参数 精确传递调用上下文,让操作始终作用于代理链的正确一端——这才是维持代理与原对象逻辑关联的关键机制。
receiver 是关联的“桥梁”
Proxy 的每个 trap(如 get/set)都接收 receiver 参数,它代表最初发起属性访问的对象,不一定是 proxy 本身。Reflect 方法(如 Reflect.get)也接受 receiver,并在内部用它来绑定 getter、确定原型链查找起点。
- 当直接访问
proxy.x,receiver 就是 proxy 实例 - 当通过继承链访问:
obj.__proto__ = proxy; obj.x,receiver 是obj,而非 proxy - Reflect.get(target, key, receiver) 会以 receiver 为 this 调用 target 上定义的 getter,确保行为符合原型链语义
不传 receiver 会导致关联断裂
如果 trap 中直接写 target[key],就丢失了 receiver 信息:
- 无法正确触发定义在原型上的 getter(因为 this 指向 target,不是原始调用者)
- Object.create(proxy) 后访问属性会失效或行为异常
- Vue 等响应式系统依赖 receiver 维持依赖收集的准确性
用 Reflect 显式转发才能延续关联
标准写法是把 receiver 透传给对应 Reflect 方法:
get(target, key, receiver) { return Reflect.get(target, key, receiver); }set(target, key, value, receiver) { return Reflect.set(target, key, value, receiver); }- 这样既保留原语义,又让整个操作链(proxy → handler → Reflect → target)始终携带原始调用上下文
receiver 还影响原型链和 this 绑定
比如目标对象有 getter:
const target = { get name() { return this.prefix + 'Tom'; } };const proxy = new Proxy(target, {
get(target, key, receiver) {
// ✅ 正确:this 指向 receiver,能读到 receiver.prefix
return Reflect.get(target, key, receiver);
}
});
const obj = { prefix: 'Mr. ' };
Object.setPrototypeOf(obj, proxy);
console.log(obj.name); // "Mr. Tom"
若写成 return target[key],this 就指向 target,prefix 读不到,结果是 undefinedTom。











