object.setprototypeof对冻结、密封、不可扩展对象及原始值(含null/undefined)均无效:冻结对象静默失败或抛typeerror;密封与不可扩展对象因内部槽位保护而拒绝;原始值直接抛typeerror;部分内置对象受引擎额外限制。

Object.setPrototypeOf 对冻结对象、密封对象和不可扩展对象无效,也会拒绝处理原始值(如数字、字符串、布尔值)以及 null 和 undefined。
冻结对象(frozen objects)
使用 Object.freeze() 冻结的对象,其 [[Prototype]] 不可被修改。此时调用 Object.setPrototypeOf 会静默失败(非严格模式)或抛出 TypeError(严格模式)。
- 冻结后原型链被锁定,引擎禁止任何原型变更
- 即使目标原型是 null 或 Object.prototype,操作仍被拒绝
密封对象(sealed objects)与不可扩展对象(non-extensible objects)
Object.seal() 和 Object.preventExtensions() 同样会阻止 setPrototypeOf 生效——因为这两类操作都限制了对象的内部属性变更,而 [[Prototype]] 属于内部槽位,受同一机制保护。
- 密封对象:自有属性不可增删改,原型也不可改
- 不可扩展对象:只禁新增属性,但按规范也隐含禁止修改 [[Prototype]]
原始值与非法输入
第一个参数必须是真实对象。传入原始类型(如 42、"hello"、true)、null 或 undefined 会立即抛出 TypeError。
- 包装对象(如 new Number(42))是对象,可被接受,但极少有实际意义
- Symbol、BigInt 等原始类型同理,无法作为第一个参数
某些内置对象的特殊限制
部分引擎对 Array、Function、Date 等内置构造器的实例施加额外约束。例如,在 V8 中对数组频繁调用 setPrototypeOf 可能触发降级,甚至在某些优化路径下直接报错。
- 不是语法层面禁止,而是运行时引擎主动拦截以保障性能与一致性
- 行为可能因 JS 引擎版本而异,不应依赖











