数组对象深拷贝再研究
常见的深层数组对象拷贝方式有,concat(),解构,JSON解析,函数递归等。
concat
var ary2 = ary1.concat();
es6解构
var ary2 = [...ary1];
var [...ary2] = ary1;
JSON解析
var ary2 = JSON.parse(JSON.stringify(ary1))
函数递归
function deepCopy(source) {
if (typeof source != "object") {
return source;
}
if (source == null) {
return source;
}
var newObj = source.constructor === Array ? [] : {}; //开辟一块新的内存空间
for (var i in source) {
newObj[i] = deepCopy(source[i]);
}
return newObj;
}
var ary2 = deepCopy(ary1);
特殊情况
这些方式都可以去实现复杂数组对象的深拷贝,如果复杂数组对象中包含函数对象,日期对象后,是否也能正常复制呢?不是的,请看:
//有下面一组数据,包含函数和时间日期特殊数据。
var arr = [{
name: '数据1',
fnc: function() {
console.log('这是函数1')
},
time: new Date(new Date().getHours()),
obj: {
name: 'vadjajkfha',
age: 19,
pov: new Array(),
time: new Date()
}
},
{
name: '数据2',
fnc: function() {
console.log('这是函数2')
},
time: new Date(new Date().getHours())
},
]
//不同方式实现深拷贝
var carr = [...arr]
var stringfyArr = JSON.parse(JSON.stringify(arr))
var copyArr = deepCopy(arr);
var catArr = arr.concat();
console.log('解构数组',carr);
靠谱
console.log('JSON复制',stringfyArr);
问题:函数直接消失, 时间变成了字符串
console.log('递归拷贝',copyArr);
问题:函数直接消失, 时间变成了字符串
console.log('concat拷贝',catArr);
靠谱
总结:使用数组对象数据时,对数据进行深拷贝,防止数据污染。
1、用es6解构赋值 或 concat是最稳妥的时间数组对象深拷贝的方式,
2、使用数组对象数据,对数据进行深拷贝,防止数据污染。
3、也可以反向操作,在通过对数据加工处理实在不方便的时候,我们可以从使用数据的地方去做类型转换。
一点点经验:
1、后端接口返回数据时,里面不会携带函数,很少有时间日期格式的数据。这种情况更多的场景是,当我们需要对数据进行二次加工时,同时需要深拷贝数组对象,有可能会发生。
2、反向操作举例:echarts 坐标轴时间渲染通过getHours()时间格式中获取小时数,可以在使用前一步将数据字符串new Date() 转换。