structuredclone能处理循环引用,这是它与json.parse(json.stringify())等方法最本质的区别;它自动识别并重建循环结构,但不支持函数、undefined、symbol等,且不克隆原型链。

structuredClone 能否处理循环引用?
能,这是它和 JSON.parse(JSON.stringify())、Object.assign()、浅拷贝最本质的区别。只要目标环境支持(Chrome 98+、Firefox 94+、Node.js 17.0+),structuredClone 就会自动识别并重建循环引用结构,不需要手动标记或打断。
注意:它不支持函数、undefined、Symbol、Promise、RegExp(部分浏览器会抛错,部分静默丢弃),也不克隆原型链上的属性——这点和 Object.assign 一致,但比 structuredClone 更“干净”。
什么时候必须用 structuredClone 而不是 JSON 方案?
当你遇到以下任一情况时,JSON.parse(JSON.stringify()) 会直接失败或静默损坏数据:
-
TypeError: Converting circular structure to JSON —— 最典型报错,说明对象含循环引用
- 嵌套了
Date、Map、Set、ArrayBuffer、TypedArray 等非 plain object 类型,JSON 会转成空对象或字符串(如 Date 变成 ISO 字符串,再 parse 回来就只是 string)
- 需要保留
BigInt 值(JSON 不支持)
TypeError: Converting circular structure to JSON —— 最典型报错,说明对象含循环引用Date、Map、Set、ArrayBuffer、TypedArray 等非 plain object 类型,JSON 会转成空对象或字符串(如 Date 变成 ISO 字符串,再 parse 回来就只是 string)BigInt 值(JSON 不支持)这时别硬改 JSON 流程,直接切到 structuredClone 是最省事的解法。
常见误用:忘记检查运行时兼容性
structuredClone 在旧版 Safari(15.4 之前)、IE、部分 Electron 内核中不可用,调用会报 ReferenceError: structuredClone is not defined。
稳妥做法是加一层检测和 fallback(仅当真需要兼容时):
function safeClone(obj) {
if (typeof structuredClone === 'function') {
return structuredClone(obj);
}
// fallback:仅限简单 plain object + array 场景,不保循环引用
return JSON.parse(JSON.stringify(obj));
}
但要注意:fallback 本身会再次触发循环引用报错,所以如果你的业务**确定有循环引用**,就不要写这种 fallback,而是强制要求环境升级,或改用第三方库(如 lodash.cloneDeep,它通过内部 tracking 支持循环,但体积大、性能略低)。
深层嵌套 + 循环引用的实际表现
假设你有如下结构:
const obj = { a: 1 };
obj.self = obj;
obj.nested = { deeper: obj };
用 structuredClone(obj) 后,返回的新对象中:result.self === result 为 true,result.nested.deeper === result 也为 true——引用关系被完整复现。这不是“深拷贝后意外相等”,而是刻意设计的行为。
容易忽略的一点:如果原对象里有 Map 或 Set 包含循环键/值,structuredClone 同样能处理,但很多开发者只测试了普通对象,没验证集合类场景,结果上线后在特定数据路径上出 bug。











