大家好,我是江城开朗的豌豆,一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript等基础前端技术,并深入掌握Vue、React、Uniapp、Flutter等主流框架,能够高效解决各类前端开发问题。在我的技术栈中,除了常见的前端开发技术,我还擅长3D开发,熟练使用Three.js进行3D图形绘制,并在虚拟现实与数字孪生技术上积累了丰富的经验,特别是在虚幻引擎开发方面,有着深入的理解和实践。
我一直认为技术的不断探索和实践是进步的源泉,近年来,我深入研究大数据算法的应用与发展,尤其在数据可视化和交互体验方面,取得了显著的成果。我也注重与团队的合作,能够有效地推动项目的进展和优化开发流程。现在,我担任全栈工程师,拥有CSDN博客专家认证及阿里云专家博主称号,希望通过分享我的技术心得与经验,帮助更多人提升自己的技术水平,成为更优秀的开发者。
目录
方法1:JSON.parse(JSON.stringify())
前几天我在项目里踩了个坑:
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. 最佳实践建议
-
简单数组 → 用展开运算符
[...arr]
-
含对象的数组 → 用
structuredClone
(浏览器支持的话) -
复杂场景 → 用Lodash的
_.cloneDeep
-
永远不要直接赋值
const copy = original
!
真实案例分享:
我在做一个任务管理系统时,因为没处理好数组复制,导致用户A的操作影响了用户B的数据...最后用structuredClone
彻底解决了问题。
你在数组复制上踩过什么坑? 欢迎在评论区分享你的血泪史! 💬