Reflect.get(target, prop, receiver)是解决Proxy代理对象访问原型属性时this绑定错误的关键,它确保属性读取时this指向receiver而非target,从而支持原型方法正确访问Proxy上的拦截逻辑和动态属性。

使用 Reflect.get 配合 receiver 参数,是解决 Proxy 代理对象访问原型属性时 this 绑定错误的关键方式。默认情况下,Proxy 的 get 拦截器中若直接用 target[prop] 访问属性,会丢失原始调用上下文,导致原型链上的方法内 this 指向错误(比如指向 target 而非实际调用者)。而 Reflect.get(target, prop, receiver) 能确保属性读取时的接收者(即 this)保持为 receiver,从而让原型方法正确运行。
为什么 receiver 参数必不可少
当 Proxy 对象继承自某个原型,并调用原型上的方法(如 obj.toString()),该方法内部常依赖 this 访问自身属性或其它方法。若在 get 拦截器中不传 receiver,而是写成 target[prop],则读取到的方法函数在执行时,this 会绑定到 target(即原始目标对象),而非当前 Proxy 实例 —— 这会导致方法内部读不到 Proxy 上的拦截属性、响应式数据或计算属性。
正确写法:始终把 receiver 传给 Reflect.get
在 Proxy 的 get 拦截器中,必须将第三个参数 receiver 显式传递给 Reflect.get,而不是省略它:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
-
Reflect.get(target, prop, receiver)✅ 正确:保留调用上下文,支持原型链访问与方法内this正确绑定 -
target[prop]❌ 错误:绕过 Proxy,丢失拦截逻辑,且this指向target -
Reflect.get(target, prop)❌ 危险:等价于Reflect.get(target, prop, target),this固定为target,无法支持代理实例的动态行为
典型场景示例:代理对象调用 toString 或自定义原型方法
假设有一个带原型方法的对象:
const proto = {
getName() { return this.name; }
};
const obj = Object.create(proto);
obj.name = 'Alice';
const proxy = new Proxy(obj, {
get(target, prop, receiver) {
// ✅ 关键:把 receiver 传进去
const value = Reflect.get(target, prop, receiver);
return typeof value === 'function' ? value.bind(receiver) : value;
}
});
console.log(proxy.getName()); // 'Alice' —— this 指向 proxy,能正确读取 name
若此处漏掉 receiver,getName 内部的 this.name 将尝试从 target(即 obj)读取 —— 表面看也行,但一旦 name 是由 Proxy 自身的 get 动态计算(如 getter 拦截),就必然失败。
进阶注意:receiver 不一定是 proxy 本身
receiver 是实际发起属性访问的对象。它可能是 Proxy 实例,也可能是继承该 Proxy 的另一个对象(如 Object.create(proxy))。因此,Reflect.get(target, prop, receiver) 能保证无论谁在原型链上触发访问,this 都准确落在最外层调用者身上,这是实现可靠继承与组合式代理的基础。

















