JavaScript中不使用JSON.stringify实现员工数组深拷贝避免指针引用
嘿,我懂你现在的困扰——你想复制员工数组,让新数组里的每个对象都完全独立,不再和原数组的对象共用引用,对吧?咱们先来拆解你之前写法的问题,再给你几个靠谱的解决方案。
为什么你的两种写法没生效?
newEmployees.assign([{}].employees);
这个写法本身语法就不对啦,Object.assign的正确用法是Object.assign(目标对象, 源对象)。就算改成Object.assign([], employees),这也只是浅拷贝数组——新数组是一个新的数组容器,但里面的每个员工对象还是和原数组里的对象指向同一个内存地址,修改新数组里的对象属性,原数组的对象也会跟着变。newEmployees = [{...employees}];
这里你把整个employees数组展开到了一个对象里,结果会得到一个类似{0: {...员工1}, 1: {...员工2}}的结构,再把这个对象塞进数组,完全不是你想要的员工数组格式。就算你改成[...employees],同样只是浅拷贝数组,里面的对象引用还是没断开。
正确的解决方案
方案1:浅拷贝(适用于对象无嵌套结构的情况)
遍历原数组,对每个员工对象单独进行复制,断开对象层面的引用:
// 使用扩展运算符 const newEmployees = employees.map(emp => ({...emp})); // 或者使用Object.assign const newEmployees = employees.map(emp => Object.assign({}, emp));
这样新数组里的每个对象都是全新的,修改新数组里的员工属性,原数组不会受到任何影响。
方案2:深拷贝(适用于对象有嵌套结构的情况)
如果你的员工对象里还有嵌套的对象(比如address: {city: 'XXX'}),上面的浅拷贝就不够用了,这时候可以用JSON.parse(JSON.stringify())实现深拷贝:
const newEmployees = JSON.parse(JSON.stringify(employees));
⚠️ 注意:这个方法有局限性,不能处理函数、undefined、Symbol类型的属性,要是你的对象里没有这些特殊类型,用它就很方便。
方案3:用第三方库(可选)
如果项目里已经在用Lodash这类工具库,可以直接用它的cloneDeep方法,省心又靠谱:
const newEmployees = _.cloneDeep(employees);
这样处理之后,新数组和原数组就完全独立啦,修改任何一方的对象都不会影响到另一方~
内容的提问来源于stack exchange,提问作者user8274065

