reflect 本身不保持上下文,关键在于 proxy 拦截器中调用 reflect 时必须显式传入 receiver 参数;否则 target 上的 getter/setter 内 this 将指向 target 而非 proxy,导致语义错误。

Reflect 本身不“保持”上下文,它只是提供一套标准化、可拦截的底层操作方法;真正决定上下文(尤其是 this)的是 Proxy 拦截器中如何调用 Reflect,并**正确传递 receiver 参数**。
receiver 参数是关键
在 Proxy 的 get、set、has 等多数 trap 中,第 3 或第 4 个参数是 receiver —— 它代表“本次操作最初发起的对象”,通常是 proxy 本身。当目标对象有访问器属性(getter/setter)或依赖 this 的计算逻辑时,receiver 就会作为 this 被传入。
如果不显式传给 Reflect,而是直接写 target[key] 或 target[key] = value,就会丢失这个 receiver,导致 this 指向 target 而非 proxy,破坏代理语义。
-
Reflect.get(target, key, receiver)→ 保证 getter 内this === receiver -
Reflect.set(target, key, value, receiver)→ 保证 setter 内this === receiver -
Reflect.has(target, key, receiver)→ 影响原型链查找时的 this 绑定(较少见但语义一致)
常见错误:漏传 receiver
下面这种写法会导致 this 错乱:
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
❌ 错误示例:get(target, key) { return target[key]; } // 没传 receiver,this 指向 targetset(target, key, value) { target[key] = value; return true; } // 同样丢失 receiver
一旦 target 上有类似 get doubleX() { return this.x * 2; } 的 getter,调用 proxy.doubleX 就会报错或返回 NaN —— 因为 this 是 target,而 target.x 可能未定义或不可访问。
为什么 Reflect 方法天然适配 receiver
Reflect 的设计初衷就是与 Proxy 协同工作。它的每个方法签名都对齐对应 trap 的参数顺序,且明确支持 receiver。这带来两个实际好处:
- 行为一致性:和原生操作(如
obj.prop)保持完全相同的语义,包括原型链查找、访问器调用、this绑定 - 可拦截性:你可以在 handler 里先做自定义逻辑(如日志、校验),再调用
Reflect.xxx(...)执行默认动作,且不破坏上下文 - 返回值规范:所有 Reflect 方法都返回布尔值或结果值(而非抛异常),便于统一处理成功/失败
实际使用建议
- 只要 trap 签名含
receiver(如get、set、apply、construct),就一定把它传给对应的Reflect方法 - 对不带
receiver的 trap(如ownKeys、deleteProperty),直接调用Reflect.ownKeys(target)即可,无需额外参数 - 不要混用:
target[key]和Reflect.get(target, key)行为不同,后者才尊重receiver和访问器










