如何判断是否存在循环引用?

可以通过 WeakMap 来保存每次遍历的对象,并合当前的对象进行比对,如果一致则认为存在循环引用。

为什么要用 WeakMap ?因为 WeakMap 是对对象的“弱”引用,一旦对象被清除,则其自身也会被垃圾回收。

示例代码

function isObject(obj) {
  return Object.prototype.toString.call(obj) === "[object Object]";
}

function isCircularReference(obj) {
  const store = new WeakMap();
  let flag = false;
  const traverse = (data) => {
    if (isObject(data)) {
      if (store.has(data)) {
        flag = true;
        return;
      }
      store.set(data, true);
      const keys = Object.keys(data);
      keys.forEach((key) => {
        traverse(data[key]);
      });
    }
  };
  traverse(obj);
  return flag;
}

var a = {
  b: 1,
  c: 2
};
a.c = a;

console.log(isCircularReference(a));

See the Pen JS 编程题 – 如何判断是否存在循环引用 by hjoker (@hjoker) on CodePen.