reflect.getprototypeof 可穿透 proxy 的 getprototypeof 拦截器直接获取目标对象真实原型;当拦截器返回 null 或伪造原型时,object.getprototypeof 和 proto 均被影响,而它仍返回 target 的 [[prototype]]。

可以通过 Reflect.getPrototypeOf 直接获取被 Proxy 包裹对象的**原始原型对象**,绕过 Proxy 中自定义的 getPrototypeOf 拦截器,实现对真实原型链的穿透访问。
为什么需要穿透 Proxy 的原型链拦截?
当 Proxy 显式设置了 getPrototypeOf 拦截器(尤其是返回 null 或伪造原型),Object.getPrototypeOf(obj) 和 obj.__proto__ 都会受其影响,无法看到真实原型。而 Reflect.getPrototypeOf 是唯一能**忽略 Proxy 拦截、强制读取底层对象原型**的标准方法。
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
Reflect.getPrototypeOf 的穿透能力验证
它不调用 Proxy 的 getPrototypeOf 拦截器,而是直接访问目标对象(target)的内部 [[Prototype]]:
- 即使 Proxy 的
getPrototypeOf返回null,Reflect.getPrototypeOf(proxy)仍返回 target 的真实原型 - 若 Proxy 未定义
getPrototypeOf拦截器,Reflect.getPrototypeOf(proxy)行为与Object.getPrototypeOf(proxy)一致 - 该方法仅适用于可代理对象(如普通对象、数组),对不可扩展/冻结对象或原始值无效
典型穿透场景示例
假设一个 Proxy 故意遮蔽原型以增强封装性:
const target = { a: 1 };
const proto = { b: 2 };
Object.setPrototypeOf(target, proto);
const proxy = new Proxy(target, {
getPrototypeOf() {
return null; // 主动遮蔽
}
});
console.log(Object.getPrototypeOf(proxy)); // null(被拦截)
console.log(proxy.__proto__); // null(同上)
console.log(Reflect.getPrototypeOf(proxy)); // { b: 2 }(穿透成功!)
注意事项与边界情况
-
Reflect.getPrototypeOf要求参数是 object 类型,传入原始值(如42、"str")会抛出TypeError - 若 Proxy 的
target本身没有原型(例如Object.create(null)),则返回null,这是真实状态,不是被遮蔽 - 不能穿透多层 Proxy 嵌套的“最内层”原型——它只作用于当前 Proxy 的
target,若target本身也是 Proxy,需递归调用 - 该方法是标准且安全的,不依赖非标准属性(如
__proto__)或私有字段










