javascript数组循环引用会导致json序列化失败、深拷贝出错或调试卡死,需用weakmap检测并缓存已访问对象,推荐structuredclone或自定义缓存深拷贝函数,序列化时可用replacer函数标记为"[circular]"。

JavaScript 数组中出现循环引用时,会导致 JSON 序列化失败、深拷贝出错、或调试工具卡死。核心思路是识别并打破引用链,或在操作时跳过已访问对象。
检测循环引用
手动检查较难,可用 WeakMap 记录已遍历对象:
- 遍历时将对象作为 key 存入 WeakMap,value 可设为 true 或路径信息
- 再次遇到同一对象时,说明存在循环引用
- 注意:WeakMap 只支持对象作 key,且不阻止 GC,适合临时追踪
安全地深拷贝含循环引用的数组
不能直接用 JSON.parse(JSON.stringify(arr)),它会报错或丢数据。推荐使用结构化克隆(现代环境)或自定义递归函数:
- Chrome 94+/Node.js 17+ 支持
structuredClone(arr),原生支持循环引用 - 兼容旧环境可手写带缓存的深拷贝函数,用 Map 缓存源对象→副本映射关系
- 遇到已拷贝过的对象,直接返回对应副本,避免无限递归
序列化时忽略或标记循环引用
JSON.stringify 本身不支持循环引用,但可通过 replacer 函数干预:
- 配合 WeakMap 记录访问路径,在 replacer 中发现重复对象时返回
"[Circular]"或 null - 也可改用第三方库如
flatted或cycle,它们能序列化/反序列化带环结构 - 调试时用
console.dir(obj, { depth: null })能显示循环引用提示(如Array [▼] → [Circular])
避免产生循环引用
多数循环引用源于手动赋值不当,例如:
- 数组项直接引用自身:
arr[0] = arr - 对象属性指向包含它的数组:
obj.arr = arr; arr.push(obj) - 构建树/图结构时未控制父子引用方向,建议用 ID 关联代替直接引用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











