核心结论
判断循环引用的关键不是对象是否“曾经出现过”,而是当前递归路径中是否再次遇到同一个对象。一个对象被不同分支共享,只构成共享引用,不一定形成环。可靠方法是进行深度优先遍历,并维护两个集合:visiting 保存当前递归路径上的对象,visited 保存已经完整检查且确认无环的对象。再次遇到 visiting 中的对象说明存在环;遇到 visited 中的对象则可以跳过。
可运行实现
function hasCircularReference(root) {
const visiting = new WeakSet();
const visited =