Object.getPrototypeOf 不检测循环原型链,仅返回对象的[[Prototype]]值;循环链由人为设置如Object.setPrototypeOf(obj, obj)导致,遍历时需用Set防重复或设深度限制。

Object.getPrototypeOf 在标准 JavaScript 环境中不会主动检测或阻止循环原型链,它只是忠实返回对象内部 [[Prototype]] 的当前值。如果原型链被人为构造出循环(例如通过 Object.setPrototypeOf 或直接赋值 __proto__),调用 Object.getPrototypeOf 本身不会报错、也不会自动终止,但后续遍历时若不加防护,会导致无限循环。
循环原型链是如何产生的
正常原型链以 null 终止,但开发者可能意外或刻意创建闭环:
- 用
Object.setPrototypeOf(obj, obj)让对象的原型指向自己 - 两个对象互相设对方为原型:
Object.setPrototypeOf(a, b); Object.setPrototypeOf(b, a) - 在跨框架或旧代码中误改
__proto__,破坏了原本的终止结构
Object.getPrototypeOf 本身的响应行为
它对循环链没有特殊处理,表现完全符合规范定义:
- 传入合法对象,就返回其
[[Prototype]]值——哪怕那个值就是它自己或形成环 - 不会抛错,也不会返回
undefined或null来“提示异常” - 也就是说:
Object.getPrototypeOf(obj)返回什么,只取决于该对象此刻的内部状态,与链是否合理无关
遍历时必须手动防循环
一旦原型链存在环,靠简单 while (p = Object.getPrototypeOf(p)) 就会卡死。安全做法是记录已访问对象:
立即学习“Java免费学习笔记(深入)”;
- 用
Set缓存见过的原型引用:if (visited.has(p)) break; - 限制最大遍历深度(如 100 层),避免长链误判为环
- 明确终止条件只能是
p === null,不能写成while (p)——因为环中对象都是真值
实际影响与建议
循环原型链不是常见场景,但一旦出现,会影响所有依赖原型链的功能:
-
instanceof可能卡住或返回错误结果 - 序列化、深拷贝、调试器展开对象时可能崩溃或无响应
-
isPrototypeOf同样无法自动识别环,需配合防重逻辑
日常开发中应避免主动构造循环原型链;排查问题时,可用 Object.getPrototypeOf 配合 Set 检测是否存在重复引用。


















