工具函数系列-判断对象中是否存在循环引用

方法1

进行序列化JSON.stringify(obj),如果存在循环引用,会报错。

function isCyclic(obj) {
    try {
        JSON.stringify(obj)
        return true
    } catch(e) {
        return false
    }
}

方法2

使用递归方法进行检测是否存在循环引用

// 参考链接:https://www.lcddjm.com/article/5cb59b32a5c16745258d66b8
function isCyclic (obj) {
  var seenObjects = [];
  
  function detect (obj) {
    if (typeof obj === 'object') {
      if (seenObjects.indexOf(obj) !== -1) {
        return true;
      }
      seenObjects.push(obj);
      for (var key in obj) {
        if (obj.hasOwnProperty(key) && detect(obj[key])) {
          return true;
        }
      }
    }
    return false;
  }
  
  return detect(obj);
}

// 使用weakSet进行改写
function checkObj(obj) {
  let objKeySet = new WeakSet()
  function circle(obj) {
    if (typeof obj === 'object' && !Array.isArray(obj)) {
      // 判断数组中是否已有 对象比较是指针比较
      if (objKeySet.has(obj)) {
        return true
      }
      objKeySet.add(obj)
      for (let key in obj) {
        if (typeof obj[key] === 'object' && circle(obj[key])) {
          return true
        }
      }
    }
    return false
  }
  return circle(obj)
}