json.stringify遇循环引用会抛typeerror,解决需提前打破循环:常用replacer函数配合weakmap标记已访问对象并返回undefined跳过;也可用structuredclone预处理断链;或引入flatted等库实现可还原的扩展json序列化。

JavaScript 中 JSON 序列化(JSON.stringify)遇到循环引用对象时会直接抛出 TypeError: Converting circular structure to JSON 错误,因为标准 JSON 格式不支持引用,无法表达对象间的循环关系。解决的核心思路是:在序列化前打破循环、跳过或替换循环引用部分。
用 replacer 函数过滤循环引用
这是最常用且轻量的方式。通过 JSON.stringify(obj, replacer) 的第二个参数——replacer 函数,对每个键值对进行拦截处理。你可以维护一个已遍历路径的 Set 或 Map,当发现某个值已被访问过(即再次出现),就返回 undefined 或占位符(如 "[Circular]"),从而避免递归进入。
- 用 WeakMap 记录已访问对象,避免内存泄漏(推荐)
- replacer 中 return
undefined会让该字段被忽略;return 字符串/数字等则会被序列化 - 注意:replacer 对数组项也生效,索引为字符串数字(如
"0"),需统一处理
使用结构克隆 + 替换策略(如 structuredClone + 自定义处理)
ES2022 引入的 structuredClone() 能安全深拷贝多数值类型(包括 Map、Set、Date 等),但它本身也不支持循环引用,会报错。不过你可以结合 structuredClone 前的预处理:先用代理(Proxy)或遍历标记法识别并“断链”,例如把循环引用字段设为 null 或特殊标记对象,再克隆和序列化。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 适合需要保留原始结构层级、仅剔除/标记循环点的场景
- 比纯 replacer 更可控,但代码稍重
- 注意:
structuredClone不支持函数、undefined、Symbol 和循环引用,仍需前置清理
借助第三方库(如 flatted、circular-json 已停更,推荐 lossless-json 或 custom serializer)
社区有专门处理循环引用的序列化方案。比如 flatted 使用整数索引替代重复引用,生成兼容 JSON 的字符串(可反序列化还原循环结构);lossless-json 支持保留 BigInt、undefined 等,并可配置循环处理策略。
- flatted 输出仍是标准 JSON 字符串,但格式扩展了引用语法(如
{"#":1}) - 引入库增加包体积,简单项目建议优先用 replacer 方案
- 若需反序列化后还原循环结构,必须用配套解析器(如
flatted.parse())
开发阶段快速排查循环引用
调试时可先用工具快速定位哪一层出现了循环。写一个简易检测函数,用 WeakMap 记录访问路径,递归遍历时一旦命中已存在对象就打印路径栈:
- 例如:
console.log("circular ref at path:", [...path].join('.')) - 配合 Chrome DevTools 的
console.dir(obj, {depth: null})查看对象结构 - 常见来源:Vue/React 组件实例、事件监听器绑定的 this、手动构造的父子双向引用(如 parent/children)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










