高效拷贝大型数组需按场景选方法:纯基本类型用slice()最快;含嵌套对象且环境支持时首选structuredClone();需兼容老浏览器或保留构造信息则用fast-copy;仅兜底时才手写WeakMap递归。

高效拷贝大型数组对象,关键不是“一招鲜”,而是根据数据结构、运行环境和性能要求选对方法。纯数字/字符串数组用 slice() 或 扩展运算符 最快;含嵌套对象且需完全隔离,现代环境首选 structuredClone();若需兼容老浏览器或保留构造信息(比如自定义类实例、Map/Set),则考虑 fast-copy 库。
纯数据型大型数组:用 slice() 或扩展运算符
如果数组只包含基本类型(number、string、boolean、null、undefined)或简单对象(无 Date、RegExp、函数等),slice() 是 V8 引擎深度优化过的原生方法,性能优于扩展运算符,尤其在超大数组(百万级元素)场景下更稳定:
-
const copy = arr.slice();—— 兼容性极好,所有浏览器和 Node.js 版本都支持 -
const copy = [...arr];—— 语法更现代,可读性强,适合日常开发;但在极端规模下略慢于 slice() - 两者都是浅拷贝,仅适用于“扁平”结构;若数组里有对象,修改对象属性仍会影响原数组
含复杂嵌套的大型数组:优先用 structuredClone()
当数组里包含 Date、RegExp、Map、Set、TypedArray 或深层嵌套对象,且你运行在 Chrome 98+、Firefox 94+、Safari 15.4+ 或 Node.js 17+(启用实验标志)环境中,structuredClone() 是目前最平衡的选择:
- 自动处理循环引用,不会栈溢出或报错
- 正确复制内置类型(如
new Date()、new Map([['a', 1]])),不转成空对象或字符串 - 无需引入依赖,开箱即用,比 JSON 方案更可靠
- 注意:不支持 function、undefined、Symbol —— 这些本就不能被结构化克隆,会直接抛
DataCloneError
高频拷贝 + 自定义类型:引入 fast-copy
如果你的大型数组频繁参与状态更新(如实时图表数据、游戏实体列表),且其中包含 React 组件、自定义类实例、包装对象(new Number(42))或 WeakMap,fast-copy 是当前性能与功能兼顾最好的方案:
立即学习“Java免费学习笔记(深入)”;
- 比
lodash.cloneDeep快 2–5 倍,简单对象可达 460 万次/秒 - 支持 Int8Array、DataView、Error 子类、带原型链的实例等 15+ 类型
- 内置循环引用检测,
copyStrict()可保留属性描述符(writable/enumerable 等) - 体积小(约 8KB),Tree-shaking 友好,适合生产环境长期使用
老环境兜底或特殊定制:手写递归 + WeakMap
仅在必须兼容 IE 或旧版 Node.js,又无法引入第三方库时才考虑手动实现。核心是用 WeakMap 缓存已拷贝对象 防止循环引用死循环,并分类处理常见类型:
- 先判断
obj !== null && typeof obj === 'object',排除原始值和 null - 查 WeakMap:已有缓存则直接返回,避免重复拷贝
- 按类型分发:
Array.isArray()→ 新数组;obj instanceof Date→new Date(obj);obj instanceof Map→new Map([...obj]) - 普通对象用
Object.getOwnPropertyDescriptors()获取全部自有属性(含 getter/setter),再用Object.defineProperties()复制 - 缺点明显:代码量大、易漏边界(如 Symbol 键、不可枚举属性)、不还原 constructor,仅建议临时过渡


















