原型链断裂本质是实例[[Prototype]]未指向对应类prototype,导致instanceof失效等;修复需从构造规范、运行时用Object.setPrototypeOf补链并验证、源头禁用错误继承写法及混淆优化。

Class 继承中原型链断裂,不是“链断了”才出问题,而是实例的 [[Prototype]] 没指向对应类的 prototype,导致 instanceof 失效、方法不可用、继承语义丢失。修复不靠“拼接”,而靠从构造源头规范、运行时精准补链、检测方式兜底。
确认是否真断裂:别猜,直接查原型链
不要看报错或 constructor.name,要用 Object.getPrototypeOf() 逐级验证:
- 执行
Object.getPrototypeOf(obj),看返回值是否等于MyClass.prototype - 若返回
null、Object.prototype或一个空对象,说明第一级已断 - 继续查:
Object.getPrototypeOf(Object.getPrototypeOf(obj)),直到为null,定位断裂位置 - 特别注意:
Object.create(null)或显式设过obj.__proto__ = null,链必然终止
修复运行时原型链:安全重设,不碰 __proto__
手动补链必须避免非标准、已废弃的 __proto__ 赋值:
- 用
Object.setPrototypeOf(obj, MyClass.prototype)安全设置第一级原型 - 若需恢复完整链(如
Child → Parent → Object),需逐级设置,或更稳妥地重建实例 - 补完立刻验证:
obj instanceof MyClass和Object.getPrototypeOf(obj) === MyClass.prototype同时为true -
Object.setPrototypeOf有性能开销,仅用于调试或紧急兜底,不可在高频路径调用
从源头预防:继承写法必须规范
多数断裂源于构建或开发阶段的误操作:
- 继承必须用
class Child extends Parent,禁用Child.prototype = {}这类直接覆盖 - 手动设置
Child.prototype = Object.create(Parent.prototype)后,务必补上Child.prototype.constructor = Child - 打包工具(如 Terser)开启
keep_classnames: true或nameCache,防止类名混淆破坏原型引用 - 禁止在实例化后主动切断链路,例如
obj.__proto__ = null或Object.assign(obj, {})导致原型丢失
绕过 instanceof:用更鲁棒的类型判断
当无法控制原型链(如第三方库对象、跨 iframe 数据),改用兼容性更强的方式:
- 用
Object.prototype.toString.call(obj)获取内部标签,前提是类设置了Symbol.toStringTag - 对内置类型优先使用专用判断:
Array.isArray(obj)、isFinite(val)、val instanceof Date(仅限同环境) - 避免依赖
constructor.name或自定义字符串匹配,易被压缩/混淆破坏


















