原型链终点是null,因ecmascript规范规定[[prototype]]值只能是对象或null,而null无[[prototype]],引擎查到即停并返回undefined,不会继续查找。

原型链的终点是 null,而 JavaScript 引擎正是靠这个 null 来终止属性查找——它不是“手动终止”,而是语言规范定义的自然终点。只要原型链走到 null,查找就停止,不会继续,因此根本不会出现死循环。
为什么 null 是终点,不会继续向上找?
根据 ECMAScript 规范,每个对象都有一个内部属性 [[Prototype]],它的值要么是另一个对象,要么是 null。当进行属性访问(如 obj.prop)时,引擎会按以下顺序查找:
- 先在对象自身检查是否有该属性(自有属性);
- 如果没有,就去
[[Prototype]]指向的对象上查找; - 如果那个对象也没有,就继续查它的
[[Prototype]]; - 直到某一步的
[[Prototype]]是null,查找立即结束,返回undefined。
关键点:规范明确规定,null 没有 [[Prototype]],也不是对象,无法再被读取原型。所以引擎不会、也不能对 null 执行下一步查找——这从底层就切断了链条。
什么情况下会误以为出现“死循环”?
实际开发中并不存在因 null 导致的死循环,但以下两种情况容易让人误解:
-
人为篡改原型链成环:比如把某个对象的
__proto__指回自己或祖先,例如obj.__proto__ = obj或A.prototype.__proto__ = B.prototype且 B 又指向 A; -
递归调用未设出口:在自定义的遍历原型链函数里忘记判断
null或重复访问同一对象,比如写错条件导致无限调用getPrototypeOf。
这些都不是 null 的问题,而是代码逻辑错误。原生属性查找机制始终安全可靠。
如何验证原型链确实以 null 终止?
可以用 Object.getPrototypeOf() 逐级向上查,观察终点:
const obj = {};
console.log(Object.getPrototypeOf(obj)); // Object.prototype
console.log(Object.getPrototypeOf(Object.prototype)); // null
console.log(Object.getPrototypeOf(null)); // TypeError: Cannot convert undefined or null to object
最后一行报错也反向印证:null 不是对象,没有原型可读——引擎在这里根本不会尝试继续,也就没有循环基础。
安全操作原型链的建议
虽然原生查找不会死循环,但为避免人为出错,推荐:
- 避免直接修改
__proto__,优先用Object.create(proto)创建指定原型的对象; - 若需遍历原型链,显式检查是否为
null或使用while (obj !== null)并记录已访问对象防环; - 调试时可用
Object.getOwnPropertyNames()+Object.getPrototypeOf()分层查看,比依赖for...in更清晰。
只要不主动制造环状结构,JavaScript 的原型链就是一条有明确起点和终点的单向链,null 就是那个不可逾越的终点。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











