避免原型链遍历死循环的关键是使用Object.getPrototypeOf获取原型、用WeakMap检测循环引用、以proto===null为唯一终止条件。

原型链遍历本身是线性向上的,但死循环通常出现在手动实现时误判了终止条件,或对象存在非法原型引用(比如循环原型链)。避免死循环的关键,是用标准 API + 显式边界检测,而不是依赖经验判断。
用 Object.getPrototypeOf 替代 __proto__
__proto__ 是非标准、已废弃的访问方式,部分环境可能被改写或返回异常值;Object.getPrototypeOf 是标准方法,行为稳定且不可被覆盖。
- 始终用 Object.getPrototypeOf(obj) 获取上一级原型
- 遇到 null 必须立即停止——这是唯一合法终点
- 不要用 obj.__proto__ === null 判断,它在某些 polyfill 或调试工具中可能失真
检测并拦截循环引用
正常原型链不会成环,但人为篡改(如 a.__proto__ = b; b.__proto__ = a)或某些框架/库的边界操作可能导致循环。必须主动识别。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 用 WeakMap 记录已访问过的对象,每次获取新原型前查表
- 一旦发现重复对象,立刻抛错或中断,避免无限递归
- 示例逻辑:visited.has(nextProto) → throw new Error("Prototype cycle detected")
明确终止边界:不只是 null
null 是终点,但不是唯一需拦截的边界。有些对象原型链不经过 Object.prototype,比如 Object.create(null) 创建的对象,其原型直接为 null;而 Function、Array 等内置类型虽路径不同,终点仍是 null。
立即学习“Java免费学习笔记(深入)”;
- 只以 Object.getPrototypeOf(obj) === null 为唯一退出条件
- 不要假设一定经过 Object.prototype —— 它可能被跳过
- 避免用 typeof obj.constructor === 'function' 等间接方式推断链长,不可靠
实际遍历工具的最小安全结构
一个健壮的遍历函数应包含三要素:标准获取、循环检测、null 终止。不需要额外抽象,简洁即安全。
- 初始化空数组和 WeakMap
- while 循环内:获取 proto → 检查是否已访问 → 推入数组 → 更新当前对象为 proto
- 每次迭代前判断 proto === null,满足则 break
- 不依赖 for 或递归,避免调用栈溢出风险

















