Object.getPrototypeOf 是定位和校验原型链的起点,用于确认 constructor 丢失是否由原型链断裂导致,并指导分两步修复:先用 Object.setPrototypeOf 重设原型,再补全 constructor 引用。

当旧版本库(如某些早期的 Babel、TypeScript 编译输出或自定义继承工具)用 __proto__ 或 Object.create(null) 等方式创建实例时,可能跳过原型链初始化,导致 constructor 属性丢失或指向错误。此时 Object.getPrototypeOf(obj).constructor 往往为 undefined 或 Object,影响类型判断、序列化、反射等逻辑。手动修复的关键不是“改 constructor”,而是**正确还原原型链并补全 constructor 引用**,而 Object.getPrototypeOf 是定位和校验原型链的起点。
确认问题:先用 Object.getPrototypeOf 检查原型链是否断裂
不要直接假设 constructor 丢失,先验证原型链是否完整:
- 调用
Object.getPrototypeOf(obj),看返回值是否为预期的类原型(如MyClass.prototype); - 若返回
null或Object.prototype,说明原型链被截断; - 再检查该原型对象上是否有
constructor属性:Object.getPrototypeOf(obj).constructor; - 常见异常:返回
undefined(原型上没定义 constructor)、Object(原型是Object.prototype)、或一个完全无关的函数。
修复策略:分两步 —— 设置原型 + 补 constructor
Object.getPrototypeOf 本身不可写,不能直接赋值,所以需用 Object.setPrototypeOf(或兼容写法)重设原型,再手动挂载 constructor:
- 先获取目标构造函数的正确原型:
const correctProto = MyClass.prototype; - 用
Object.setPrototypeOf(obj, correctProto)修正原型链; - 确保
correctProto.constructor === MyClass,若不成立(如被污染),手动修复:correctProto.constructor = MyClass; - 注意:仅对单个实例调用
setPrototypeOf不影响其他实例,安全可控。
防御性封装:自动识别并注入缺失 constructor
可写一个通用修复函数,利用 Object.getPrototypeOf 做条件判断,避免重复操作:
function fixConstructor(obj, expectedCtor) {
const proto = Object.getPrototypeOf(obj);
if (!proto || proto.constructor !== expectedCtor) {
Object.setPrototypeOf(obj, expectedCtor.prototype);
// 确保 prototype 上 constructor 正确
if (expectedCtor.prototype.constructor !== expectedCtor) {
expectedCtor.prototype.constructor = expectedCtor;
}
}
return obj;
}
// 使用
const brokenInst = legacyLib.createSomething(); // constructor 丢失
fixConstructor(brokenInst, MyActualClass);
console.log(brokenInst.constructor === MyActualClass); // true
替代方案与注意事项
- 避免在生产环境频繁调用
Object.setPrototypeOf,它有性能开销且禁用 V8 的部分优化;优先在实例化后立即修复; - 若无法获知
expectedCtor(如泛型场景),可尝试从上下文推断,或借助instanceof+ 已知类列表回溯; - ES6 class 继承中,子类必须调用
super(),否则this未初始化,此时Object.getPrototypeOf(this)会报错 —— 这属于语法错误,不在 runtime 修复范畴; - 对于
Object.create(null)创建的对象,它本就没有 constructor,修复前需明确业务是否真需要模拟“类实例”行为。

















