跳转到内容

判断对象循环引用

刀刀

6/17/2025

0 字

0 分钟

判断条件

判断一个对象是否循环引用,需要满足以下条件:

  1. 对象的某个属性值等于该对象本身。
  2. 对象某个属性值和其同级属性值相同不算循环引用。

思路实现

封装一个 hasCircRef 函数,接收一个参数 target ,首先判断 target 是否为对象,如果不是对象直接返回 false,然后判断 target 是否为 null,如果是 null 也直接返回 false

然后递归 for...in 遍历 target 的所有属性,递归调用 hasCircRef 函数。此时调用该函数会出现栈溢出的情况。

js
function hasCircRef(target) {
  if (typeof target !== 'object' || target === null) {
    return false;
  }
  for (let key in target) {
    hasCircRef(target[key]);
  }
}

因此需要解决栈溢出的问题,解决思路是参数再接收一个 Set ,用来存储已经遍历过的对象,如果当前遍历的对象在 Set 中存在,则说明存在循环引用,返回 true;否则说明没出现过,add() 保存一份。直到递归遍历结束。

js
function hasCircRef(target, seen = new Set()) {
  if (typeof target !== 'object' || target === null) {
    return false;
  }


  if (seen.has(target[key])) { 
    return true; 
  } 
  seen.add(target[key]); 

  for (let key in target) {
    if (hasCircRef(target[key], seen)) { 
      return true; 
    } 
  }

  return false; 
}

Bug 修改

代码实现到目前,有一个 bug 需要解决,看一个例子:

js
const obj = {
  a: {
    b: 1
  }
}
obj.c = obj.a;

这种情况下函数也会返回 true ,但是