怎么判断循环引用?

判断循环引用的方式主要有两种:

  1. 可以使用 JSON.stringify() 方法将对象转为字符串,在转化过程中,JSON.stringify() 方法会检测对象中是否存在循环引用。如果存在循环引用,则转化会出现异常,捕获到异常后即可判断出对象中存在循环引用。
let obj1 = {
  name: 'Tom'
};
let obj2 = {
  name: 'Jerry',
  friend: obj1
}
obj1.friend = obj2;

let hasCircularReference = false;
try {
  JSON.stringify(obj1);
} catch (e) {
  hasCircularReference = true;
}
console.log(hasCircularReference); // 输出 true
  1. 通过设置一个 Set 数据结构来记录已经遍历的对象,当遍历到已经在 Set 中存在的对象时,说明出现了循环引用。需要注意的是,当遇到子对象时需要递归遍历,并将已经遍历过的对象记录在 Set 中。
function hasCircularReferences(obj, set = new Set()) {
  if (obj === null || typeof obj !== 'object') {
    return false;
  }

  if (set.has(obj)) {
    return true;
  }

  set.add(obj);
  for (let key in obj) {
    if (hasCircularReferences(obj[key], set)) {
      return true;
    }
  }
  return false;
}

let obj1 = {};
let obj2 = {};
obj1.friend = obj2;
obj2.friend = obj1;
console.log(hasCircularReferences(obj1)); // 输出 true

不同的应用场景需要选择不同的判断方式。如果需要直接将对象转为字符串,以满足某些需要字符串作为参数的 API,第一种方式是一个不错的选择。如果需要进行更加灵活、严谨的操作,例如从对象中提取相关属性,重建出一个不带循环引用的新对象,使用第二种方式就比较方便。

posted @ 2023-06-05 06:26  kitebear  阅读(373)  评论(0编辑  收藏  举报