structuredClone能直接处理循环引用,是其最不可替代的优势之一;它用图遍历重建引用关系,一行代码即可实现完全隔离的深拷贝,无需手动缓存或递归逻辑。
能,而且是它最不可替代的优势之一。JSON 方法遇到 obj.self = obj 这类结构会直接抛 TypeError: Converting circular structure to JSON,而 structuredClone 内部用图遍历而非树遍历,天然支持循环引用重建。
实操时只需一行:
const original = { name: "user" }; original.ref = original;const clone = structuredClone(original);console.log(clone.ref === clone); // true
WeakMap 缓存,不用写递归逻辑clone.ref 指向的是新对象自身,不是原对象,完全隔离能,且比 JSON 方案强得多——它保留类型、长度、内容,甚至支持底层内存转移优化。
常见错误是误以为 Uint8Array 被转成普通数组或丢失精度:
const arr = new Uint8Array([1, 2, 3]);const clone = structuredClone(arr);console.log(clone instanceof Uint8Array); // trueconsole.log(clone[0] === arr[0]); // true
transfer 选项时,是完整复制(深拷贝),原 arr.buffer 仍可用{ transfer: [arr.buffer] },此时原 arr.buffer 变为 detached,必须确保后续不再读写ArrayBuffer、MessagePort 等可转移对象,传 Uint8Array 本身会报错它不报错才奇怪——遇到不支持类型会立即抛 DataCloneError,而不是静默丢弃。最容易踩坑的是这三类:
function:哪怕只是对象里一个方法字段,structuredClone({ fn() {} }) 直接失败undefined 或 Symbol(包括 Symbol('key'),但 Symbol.for('key') 可克隆)Error 实例:属性能拷贝,但 stack、原型链、cause 字段全丢失,且某些环境可能抛错业务中常混在配置对象或响应数据里,建议提前过滤或降级:
try { return structuredClone(data);} catch (err) { if (err.name === 'DataCloneError') { return JSON.parse(JSON.stringify(data)); // 仅限纯数据场景 } throw err;}
不能只靠 typeof structuredClone === 'function' 判断——Node.js 17+ 和现代浏览器支持,但 Safari 15.4 之前、Firefox 94 之前等旧版本不支持,且部分 Electron 或 WebView 环境可能未启用。
structuredClone({ a: 1, b: new Date() }),Date 是 JSON 不支持但 structuredClone 支持的典型信号JSON.parse(JSON.stringify()) 前,务必确认数据不含 Date、RegExp、BigInt,否则结果不可控真正复杂的业务对象,往往同时含循环引用 + TypedArray + 部分不可克隆字段——这种时候,没有银弹。要么清洗输入(剔除函数/undefined),要么接受降级损失,要么引入轻量 polyfill(如基于 postMessage 的跨 context 克隆)。