原型链断裂表现为调用方法或访问属性时出现undefined或TypeError,根本原因是__proto__链被赋值为null等操作意外中断;可通过Object.getPrototypeOf逐级检查链是否过早终止至null来确认,常见原因包括显式设__proto__=null、Object.create(null)、Object.setPrototypeOf(obj, null)及JSON序列化丢失原型。

原型链断裂通常表现为调用方法或访问属性时出现 undefined 或 TypeError: xxx is not a function,根本原因是对象的 __proto__ 链在某处意外中断(比如被赋值为 null),导致无法向上查找到预期的原型方法。
确认是否发生了原型链断裂
最直接的方式是手动检查对象的原型链是否连贯:
- 用
Object.getPrototypeOf(obj)逐级向上获取原型,直到返回null; - 对比正常对象(如
{})的原型链:其终点应是Object.prototype → null; - 若某步返回
null过早(例如新建对象后立刻执行了obj.__proto__ = null),就说明链已断裂。
常见导致断裂的操作要警惕
以下写法会主动切断原型链,需特别注意:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
obj.__proto__ = null(显式断开); -
Object.create(null)创建的对象天生无原型,所有属性查找都止于自身; - 使用
Object.setPrototypeOf(obj, null)动态移除原型; - 某些深克隆库或序列化/反序列化逻辑(如
JSON.parse(JSON.stringify(obj)))会丢失原型信息,生成纯数据对象。
快速定位断裂点的调试技巧
在控制台中运行这段检查脚本,能可视化原型路径:
立即学习“Java免费学习笔记(深入)”;
function traceProto(obj, label = 'obj') {
let chain = [];
let current = obj;
while (current !== null && current !== undefined) {
chain.push(current.constructor?.name || '[object]');
current = Object.getPrototypeOf(current);
}
console.log(`${label} 原型链:`, chain.join(' → '));
}
// 使用示例
const a = {};
traceProto(a); // "obj 原型链: Object → [object]"
const b = Object.create(null);
traceProto(b); // "obj 原型链: [object]"(只有自身,无 Object.prototype)
修复与预防建议
断裂本身不是错误,但若依赖原型方法就必须避免:
- 避免手动设置
__proto__ = null,除非明确需要“字典式”对象(如用作 map); - 需要用
Object.create(null)时,改用Map或显式挂载所需方法; - 构造函数中慎用
this.__proto__ = null,优先用class语法或Object.setPrototypeOf(this, YourClass.prototype); - 对可能被序列化的对象,用
Object.assign({}, obj)或结构赋值代替Object.create(null),保留默认原型。

















