JavaScript篇:JavaScript数组复制:深拷贝vs浅拷贝,你真的懂了吗?

 大家好,我是江城开朗的豌豆,一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript等基础前端技术,并深入掌握Vue、React、Uniapp、Flutter等主流框架,能够高效解决各类前端开发问题。在我的技术栈中,除了常见的前端开发技术,我还擅长3D开发,熟练使用Three.js进行3D图形绘制,并在虚拟现实与数字孪生技术上积累了丰富的经验,特别是在虚幻引擎开发方面,有着深入的理解和实践。

        我一直认为技术的不断探索和实践是进步的源泉,近年来,我深入研究大数据算法的应用与发展,尤其在数据可视化和交互体验方面,取得了显著的成果。我也注重与团队的合作,能够有效地推动项目的进展和优化开发流程。现在,我担任全栈工程师,拥有CSDN博客专家认证及阿里云专家博主称号,希望通过分享我的技术心得与经验,帮助更多人提升自己的技术水平,成为更优秀的开发者。

目录

1. 浅拷贝:只复制一层

方法1:展开运算符(最常用)

方法2:Array.slice()

方法3:Array.from()

2. 当数组包含对象时:浅拷贝的坑

3. 深拷贝:彻底克隆

方法1:JSON.parse(JSON.stringify())

方法2:使用Lodash的cloneDeep

方法3:structuredClone(现代浏览器API)

4. 性能大比拼

5. 最佳实践建议


前几天我在项目里踩了个坑:

const myPlaylist = ['晴天', '夜曲', '七里香'];
const copiedPlaylist = myPlaylist;
copiedPlaylist.push('告白气球');

console.log(myPlaylist); 
// 输出:['晴天', '夜曲', '七里香', '告白气球'] 😱

WTF?!我只是想复制个数组,怎么原数组也被改了?

原来在JS中,直接赋值只是创建了一个引用,而不是真正的复制。今天我们就来彻底搞懂JavaScript数组复制的正确姿势!


1. 浅拷贝:只复制一层

方法1:展开运算符(最常用)

const mySkills = ['React', 'Vue', 'Node'];
const copiedSkills = [...mySkills];

copiedSkills.push('GraphQL');
console.log(mySkills); // ['React', 'Vue', 'Node'] ✅ 原数组不变

方法2:Array.slice()

const myTools = ['VSCode', 'Chrome', 'Postman'];
const copiedTools = myTools.slice();

copiedTools.pop();
console.log(myTools); // ['VSCode', 'Chrome', 'Postman'] ✅

方法3:Array.from()

const myHobbies = ['coding', 'gaming', 'music'];
const copiedHobbies = Array.from(myHobbies);

⚠️ 但这些方法有个致命问题...


2. 当数组包含对象时:浅拷贝的坑

const myProjects = [
  { name: '电商网站', progress: 80 },
  { name: '后台管理系统', progress: 50 }
];

const copiedProjects = [...myProjects];
copiedProjects[0].progress = 100;

console.log(myProjects[0].progress); // 100 😱 原数组被改了!

为什么?
因为浅拷贝只复制了第一层,里面的对象仍然是引用


3. 深拷贝:彻底克隆

方法1:JSON.parse(JSON.stringify())

const myData = [
  { name: '我', age: 18 },
  { skills: ['JS', 'CSS'] }
];

const deepCopiedData = JSON.parse(JSON.stringify(myData));
deepCopiedData[0].age = 25;

console.log(myData[0].age); // 18 ✅ 原数据没变

⚠️ 局限性:

  • 不能复制函数、undefined、循环引用

  • 日期对象会变成字符串

方法2:使用Lodash的cloneDeep

import _ from 'lodash';

const complexData = [
  { user: '我', meta: { createdAt: new Date() } }
];

const deepCopy = _.cloneDeep(complexData);

方法3:structuredClone(现代浏览器API)

const original = [{ name: '我', friends: ['A', 'B'] }];
const cloned = structuredClone(original);

4. 性能大比拼

方法适用场景速度支持深拷贝
[...arr]简单数组⚡⚡⚡⚡⚡
arr.slice()简单数组⚡⚡⚡⚡
JSON方法一般对象⚡⚡
structuredClone复杂对象⚡⚡⚡
Lodash极端情况

5. 最佳实践建议

  1. 简单数组 → 用展开运算符 [...arr]

  2. 含对象的数组 → 用 structuredClone(浏览器支持的话)

  3. 复杂场景 → 用Lodash的_.cloneDeep

  4. 永远不要直接赋值 const copy = original


真实案例分享
我在做一个任务管理系统时,因为没处理好数组复制,导致用户A的操作影响了用户B的数据...最后用structuredClone彻底解决了问题。

你在数组复制上踩过什么坑? 欢迎在评论区分享你的血泪史! 💬

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江城开朗的豌豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值