必须显式传递 receiver 参数,因为 reflect.get 的第三个参数决定 getter 中 this 的指向;省略时默认为 target,导致 this 绑定错误、getter 行为异常及原型链访问失效。

在 Proxy 的 get 拦截器中使用 Reflect.get 时,必须显式传入 receiver 参数,否则会丢失原始调用上下文,导致 this 绑定错误或访问器属性(getter)行为异常。
为什么 receiver 必须显式传递?
Reflect.get(target, key, receiver) 的第三个参数 receiver 决定了 getter 中 this 的指向。若省略,receiver 默认为 target,而非实际被访问的对象(即 Proxy 实例或其继承链上的对象),这会破坏原型链上 getter 的正确执行逻辑。
例如:当 Proxy 包裹一个有 getter 的对象,且该 getter 依赖 this 访问其他属性时,不传 receiver 就会导致 this 指向错误目标,读取结果出错。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
正确写法:始终把 receiver 作为第三个参数传入
Proxy 的 get 拦截器签名是 get(target, key, receiver),其中 receiver 就是触发本次 get 的原始对象(通常是 Proxy 实例本身)。应直接将其透传给 Reflect.get:
const obj = {
_value: 42,
get value() { return this._value; }
};
const proxy = new Proxy(obj, {
get(target, key, receiver) {
console.log('get triggered on:', receiver === proxy); // true
return Reflect.get(target, key, receiver); // ✅ 正确:receiver 透传
}
});
proxy.value; // → 42,this 在 getter 中指向 proxy(符合预期)
常见错误与对比
-
错误:省略 receiver ——
Reflect.get(target, key)
→this在 getter 中指向target,不是proxy,可能读不到代理层定义的属性或方法。 -
错误:硬编码 receiver 为 target ——
Reflect.get(target, key, target)
→ 完全绕过 Proxy,失去拦截意义,且破坏继承关系(如子类访问父类 getter)。 -
正确:原样传递 receiver ——
Reflect.get(target, key, receiver)
→ 保持语义一致性,确保 getter、Object.prototype.toString等依赖this的操作正常工作。
receiver 还影响哪些场景?
除了普通 getter,以下情况都依赖正确的 receiver:
- 通过
Object.create()构建的原型链上定义的 getter/setter; - 类中定义的 getter,尤其当 Proxy 代理的是子类实例时;
- 某些内置方法(如
Array.prototype.map内部读取length)在 Proxy 数组中触发 get 时; - 使用
with语句(虽已废弃)或 Proxy 作为上下文对象时的属性查找。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










