
本文介绍 `structuredclone()` 这一现代原生 api,它能安全、高效地对包含 date、map、set、regexp、arraybuffer 等复杂类型的数组执行**深拷贝**,确保新数组与原数组完全隔离,且不丢失数据类型语义。
在 JavaScript 中,浅拷贝(如展开运算符 [...a]、slice()、Array.from())仅复制数组第一层引用,内部嵌套的对象、日期、正则等仍共享内存地址——修改副本中的嵌套属性会意外影响原始数据。而 JSON.parse(JSON.stringify()) 虽可实现深拷贝,却存在严重局限:它会序列化 Date 为字符串、丢弃 undefined、Function、Symbol、BigInt、RegExp、Map、Set 等不可序列化值,导致数据失真。
所幸,现代浏览器和 Node.js(v17.0+ 默认启用,v18.13+ 稳定支持)已原生提供 structuredClone() ——一个专为结构化克隆算法(Structured Clone Algorithm)设计的标准 API。它不仅能完整保留 Date、RegExp、Map、Set、ArrayBuffer、TypedArray、Error 等内置对象的类型和状态,还能正确处理循环引用(自动避免无限递归),且性能优于手写递归深拷贝。
以下是一个典型示例:
const a = [1, new Date('2023-07-19T10:35:21'), false, {
date: new Date('2023-07-19T10:35:21'),
name: "John Doe",
nested: { id: 42 }
}];
const b = structuredClone(a);
// ✅ 完全独立的引用
console.log(a === b); // false
console.log(a[1] === b[1]); // false(两个 Date 实例不同)
console.log(a[3] === b[3]); // false
console.log(a[3].nested === b[3].nested); // false
// ✅ 修改副本不影响原始数据
b[3].date = null;
b[3].nested.id = 999;
console.log(a[3].date); // Date { ... }(未被修改)
console.log(a[3].nested.id); // 42(原始值保持不变)
console.log(b[3].date); // null
console.log(b[3].nested.id); // 999⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 兼容性:需检查运行环境支持情况(caniuse.com/structured-clone)。对于不支持的旧环境(如 IE、旧版 Safari),可使用 @ungap/structured-clone 等轻量 polyfill。
- 限制类型:structuredClone() 不支持 function、undefined、Symbol、WeakMap、WeakSet 和 window 对象等非可传输(non-transferable)值——尝试克隆会抛出 DataCloneError。
- 性能提示:对超大嵌套结构,structuredClone() 仍优于多数手动实现;但若需精细控制(如忽略某些字段或自定义转换逻辑),仍建议封装带策略的深拷贝工具函数。
✅ 总结:当目标是「获得一个与原数组内容一致、但所有嵌套对象/值均拥有全新内存引用」时,structuredClone() 是当前最标准、最可靠、最简洁的解决方案。无需自行实现递归逻辑,也无需妥协于 JSON 序列化的类型损失——只需一行代码,即可达成真正意义上的深度克隆。










