Object.setPrototypeOf 比 proto 更安全可控,但二者均会触发引擎去优化、损害性能;__proto__ 隐式危险且不规范,应禁止使用;setPrototypeOf 是显式合规的兜底方案,仅限必要场景。

Object.setPrototypeOf 比直接赋值 __proto__ 更安全、更可控,但两者在性能上其实“一样差”——关键不是谁更快,而是都该避免在热路径中使用。
真正影响性能的,是“修改原型”这个动作本身,而非用哪种方式改。V8 等引擎一旦发现对象的 [[Prototype]] 被动态变更,就会立刻放弃对该对象的隐藏类优化,触发去优化(deoptimization),后续所有属性访问和方法调用都会变慢。
不过,__proto__ 的问题更隐蔽、更危险:
- 它在严格模式下直接报错,部分旧环境(如某些嵌入式 JS 引擎)甚至不支持
- 语义模糊:看起来像普通属性,实则是访问器,容易被误读或误删
- 引擎难以统一管控,可能绕过内部一致性检查,导致缓存失效更 unpredictably
而 Object.setPrototypeOf 的设计意图明确,失败时统一抛 TypeError,便于捕获和调试;也更容易被工具链识别和拦截(比如 ESLint 规则可禁用 __proto__,却难禁用 setPrototypeOf 的误用)。
所以性能差异不是重点,重点是:
- 两者都会破坏引擎优化,不要指望“换写法就能提速”
__proto__ = ...是隐式、不可控、不规范的写法,应彻底禁止Object.setPrototypeOf(...)是显式、可检测、符合标准的兜底手段,仅用于必要场景
常见误用场景包括:试图用它做“运行时继承切换”“动态混入行为”,其实多数可用 Object.create、class 或组合委托替代。
一句话总结:不是哪个更快,而是哪个更值得信任——答案是 Object.setPrototypeOf;但最好的选择,是根本不用。


















