背景
最近在做数据处理的过程中,遇到一个问题,如下:
后台传递过来一组数据 Array
,每个数组元素里面又包含了子对象,我要对这组数据进行处理,但是不想影响到原数组,同时原数组可能会要进行多个方向的数据格式化,为了渲染不同的界面。
原始数据
let data = [
{
id: 1,
name: 'luoxue',
age: 25
},
{
id: 2,
name: 'kk',
age: 22
},
{
id: 3,
name: 'qiuxia',
age: 22
}
];
处理方案
1、直接用 =
赋值
let myData = data; // 我要的数据
let yourData = data; // 你要的数据
myData[0].name = 'luoxue-xu'; // 我要修改成我的名字
yourData[0].name = 'kk-z'; // 你要修改成你的名字
console.log(data[0].name); // kk-z
不管是对 myData
还是对 yourData
操作,都改变了原来的 data
,我心慌啊,原数据怎么能乱动呢,要是它主人追究怎么办?我又弱又饿,跑不过也打不过,左思右想,有了第二种思路。
2、用 slice
来实现数组的拷贝,先试试
let myData = data.slice(0); // 传入0 表示截取全部
let yourData = data.slice(0); // 你家的
myData[0].name = 'luoxue-xu'; // 我要修改成我的名字
console.log(data[0].name); // luoxue-xu
看到结果我又懵了,你这是几个意思啊,我死了两千多个脑细胞才想出来的思路,竟然还是会改变,查询的资料显示 slice
确实可以实现拷贝而不改变原数组的功能啊,难道看漏了。
再认真看了遍资料,有点思绪,slice
虽然返回的是一个新数组,但是元素如果是对象,该引用的还是引用,原来如此。slice
相当于数组的浅拷贝,如果数组中的元素是基本类型,那就可以通过它来实现拷贝。
江湖走马,风也好,雨也罢 ------《道君》
3、用 JSON
转,先转字符串,再转回对象
let myData = JSON.parse(JSON.stringify(data)); // 我家的
let yourData = JSON.parse(JSON.stringify(data)); // 你家的
yourData[0].name = 'kk-z'; // 你名字带走
console.log(data[0].name); // luoxue
咦,还有点靠谱的样子,竟然可以,这么简单,不会有什么坑吧,先用着试试,不过 jQuery.extend
也可以实现,难道它也是这样做的,不太可能,再思考思考。
4、自己写个深拷贝的函数 clone
const clone = (b) => {
if(Array.isArray(b)) {
// 数组拷贝
let obj = [];
for(let i = 0; i < b.length; i++) {
obj[i] = clone(b[i]);
}
return obj;
}else if(b instanceof Object) {
// 对象拷贝
let obj = {};
for(let attr in b) {
obj[attr] = clone(b[attr]);
}
return obj;
}else {
return b;
}
}
let myData = clone(data); // 我家的
let yourData = clone(data); // 还是我家的
yourData[0].name = 'luoxue-kk'; // 还是我家的
console.log(data[0].name); // 返回什么,不告诉你,虽然报错了.
有空可以研究一下 Object.assign
的使用。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。