structuredClone 支持循环引用,采用图遍历重建引用关系,克隆后新对象间保持等价循环链接;仅限可结构化数据,遇函数、DOM 节点等抛 DataCloneError,需注意浏览器兼容性与前置校验。

structuredClone 对循环引用结构的支持是它区别于其他拷贝方式的核心能力之一——它能自动识别并重建完整的引用关系,而不是报错或丢弃。
structuredClone 确实支持循环引用,且行为可预测
它内部采用图遍历(graph traversal)而非树遍历,因此能正确处理 obj.self = obj 或更复杂的嵌套循环(如 A → B → C → A)。克隆后,新对象中所有循环链接都会被映射为新对象之间的等价引用,完全隔离于原对象。
-
clone.self === clone会返回true - 若
obj.nested = { ref: obj },则clone.nested.ref === clone也为true - 所有层级的循环(包括 Map/Set 中的循环键/值)都被保留
但它对“循环”的定义很严格:只支持可结构化数据间的循环
立即学习“Java免费学习笔记(深入)”;
- ✅ 支持:普通对象、数组、Date、Map、Set、ArrayBuffer、TypedArray 内部形成的循环
- ❌ 不支持:函数、Promise、WeakMap、DOM 节点、Symbol(非 Symbol.for)、undefined 等非结构化值参与的循环——遇到即抛
DataCloneError
实际使用中需注意三点
- 浏览器兼容性必须达标:Chrome 98+、Firefox 94+、Safari 15.4+、Node.js 18.16+ / 20.6+
- 不要试图 fallback 到
JSON.parse(JSON.stringify())处理循环引用——这会直接失败,不是降级而是退路失效 - 如果对象里混入了函数或 DOM 元素,structuredClone 会立刻报错,不能静默跳过;建议提前清理或封装校验逻辑
简单验证示例
const obj = { x: 1 };
obj.loop = obj;
obj.child = { parent: obj };
const clone = structuredClone(obj);
console.log(clone.loop === clone); // true
console.log(clone.child.parent === clone); // true不复杂但容易忽略


















