Proxy 通过 setPrototypeOf 和 getPrototypeOf 两个 trap 拦截原型链的设置与读取操作,前者校验并控制原型赋值,后者动态返回原型对象或 null;但无法捕获 Object.create()、构造函数初始化等非代理对象修改行为。

Proxy 本身不直接“捕获原型链修改”,而是通过特定的 trap 拦截与原型链相关的操作——关键在于 setPrototypeOf 和 getPrototypeOf 这两个捕捉器。
用 setPrototypeOf 捕获原型设置行为
当代码试图修改对象原型时(如 Object.setPrototypeOf(obj, newProto) 或非标准的 obj.__proto__ = newProto),只要该对象是 Proxy,且 handler 中定义了 setPrototypeOf trap,就会被拦截:
- 该 trap 接收两个参数:
target(原始目标对象)和prototype(拟设的新原型) - 必须返回布尔值:返回
true表示设置成功,false表示拒绝(在严格模式下会抛错) - 推荐使用
Reflect.setPrototypeOf(target, prototype)转发,保持语义一致 - 可在此处加入校验逻辑,比如禁止设为
null、限制只允许特定构造函数的原型等
用 getPrototypeOf 捕获原型读取行为
所有读取原型的操作都会触发它,包括:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
Object.getPrototypeOf(proxy)-
proxy.__proto__(尽管已弃用) -
proxy instanceof SomeClass(因为 instanceof 内部调用getPrototypeOf并遍历链)
这个 trap 返回值必须是对象或 null,否则会抛 TypeError。你可以:
- 返回原 target 的原型(默认行为)
- 返回一个动态合成的对象(例如多个 mixin 的委托组合)
- 返回
null来切断原型链(慎用,会影响 instanceof 和属性继承)
注意无法拦截的“伪修改”
有些看似改原型的操作,Proxy 实际无法捕获:
- 直接赋值
proxy.__proto__ = ...在某些引擎中可能绕过 trap(尤其非严格模式),应避免使用 -
Object.create()创建新对象时指定原型,不涉及已有对象的修改,自然不触发任何 trap - 构造函数内部的
this.__proto__初始化也不走 Proxy trap,属于实例创建阶段行为
配合其他 trap 增强一致性
仅靠原型相关 trap 不足以完整模拟或控制继承行为,还需协同:
-
get:确保属性访问时receiver正确,维持 this 绑定和查找起点 -
has和ownKeys:让in操作符和枚举能反映“逻辑上”的原型属性,而非仅 target 自有属性 -
isExtensible和preventExtensions:控制对象是否可扩展,间接影响原型链稳定性

















