structuredClone 是浏览器原生深拷贝 API,能正确保留 Date、Map、Set 等内置对象类型,避免 JSON 方式导致的类型丢失或错误;但不支持函数、Symbol、WeakMap、循环引用等,需按场景选替代方案。

structuredClone 是浏览器原生提供的深拷贝 API,能正确处理 Date、Map、Set、RegExp、ArrayBuffer 等内置可转移对象,**无需手动递归或特殊判断**,自然规避传统 JSON 序列化方式(如 JSON.parse(JSON.stringify(obj)))对 Date 变成字符串、Map/WeakMap 丢失等导致的逻辑错误。
为什么传统深拷贝在 Date 和 Map 上容易出错
常见错误来源:
-
JSON.stringify(new Date())→ 字符串"2024-05-10T08:23:15.123Z",再JSON.parse得到的是普通字符串,不是Date实例,调用.getTime()或.toISOString()直接报错 -
JSON.stringify(new Map([['a', 1]]))→ 空对象{},Map 结构完全丢失,后续map.get('a')返回undefined - 手写递归拷贝若未显式处理
Date构造或Map迭代逻辑,也会漏掉类型还原
structuredClone 的正确用法(兼容性注意)
直接传入目标对象即可,返回一个结构相同、内存独立的新对象:
const original = {
time: new Date('2024-05-10'),
cache: new Map([['key', { value: 42 }]])
};
const cloned = structuredClone(original);
console.log(cloned.time instanceof Date); // true
console.log(cloned.cache instanceof Map); // true
console.log(cloned.cache.get('key').value === 42); // true
console.log(cloned.time.getTime() === original.time.getTime()); // true(值相等)
console.log(cloned.time === original.time); // false(不同引用)
注意:目前(截至 2024 年中)structuredClone 在现代 Chrome、Edge、Firefox、Safari 中已稳定支持;Node.js 自 17.0 起支持(需启用 --experimental-structured-cloning 标志,v18.16+ 默认启用);旧版浏览器需降级方案(如 import 'core-js/full/structured-clone' 或检测后 fallback)。
哪些情况仍会报错?如何规避
structuredClone 不是万能的,以下类型仍会抛 DataCloneError:
- 函数(
function)、undefined、Symbol、WeakMap、WeakSet、Error对象、DOM 节点、Window等不可序列化对象 - 含有循环引用的对象(会明确报错,而非静默失败)
应对建议:
- 确保待拷贝对象只含可克隆类型(优先设计数据类对象,避免混入函数或 DOM)
- 提前过滤或替换不可克隆字段(例如将
cache: new Map(...)保留,但移除onUpdate: () => {...}) - 对含循环引用的场景,改用专用库(如
lodash.cloneDeep),或先用structuredClone+ 手动修复循环(较复杂,一般应避免)
替代方案对比(何时不用 structuredClone)
如果项目需兼容 IE 或老旧 Node 版本,可考虑:
-
lodash.cloneDeep:成熟稳定,自动处理 Date/Map/RegExp/循环引用,但体积较大(tree-shaking 后约 10KB) - 自定义轻量克隆函数:仅覆盖项目实际用到的类型(如只处理 Date + Map + plain object + array),代码可控、无依赖
- 不深拷贝,改用不可变更新(如
immer):更适合状态管理场景,避免拷贝开销
只要运行环境支持,structuredClone 就是最简洁、最可靠的选择——它由引擎实现,性能好,语义准,且随标准演进持续增强。

















