在开发过程中我们经常会遇到需要对复杂数据进行数据处理的同时不要对原数据有任何的影响,那么这种情况就需要拷贝出来一份数据,然后对拷贝出来的数据进行修改,但由于js对于复杂数据类型是复制的地址,所以无论修改哪个另一个都会收到影响
问题展现:
const obj = {
name: '张三',
age: 18
}
const obj1 = obj
obj.name = '李四'
console.log(obj) // {name: '李四', age: 18}
console.log(obj1) // {name: '李四', age: 18}
————————————————————————————————————————————————————————
解决办法:
方法1 :
const obj = {
name: '张三',
age: 18,
hobby: ['唱', '跳', 'rap', '篮球'],
};
const obj1 = { ...obj };
obj1.name = '李四';
obj1.hobby.push('你干嘛');
console.log(obj); // {name: '张三', age: 18, hobby: ['唱', '跳', 'rap', '篮球', '你干嘛']
console.log(obj1); // {name: '李四', age: 18, hobby: hobby: ['唱', '跳', 'rap', '篮球', '你干嘛']
由此可以看出,这种方法只能拷贝出来第一层,所以只有第一层不受影响,只要一深入还是会互相影响的,所以这种方法一般用在数据只有一层的情况
————————————————————————————————————————————————————————
方法2:
const obj = {
name: '张三',
age: 18,
hobby: ['唱', '跳', 'rap', '篮球'],
};
const obj1 = JSON.parse(JSON.stringify(obj));
obj1.name = '李四';
obj1.hobby.push('你干嘛');
console.log(obj); // {name: '张三', age: 18, hobby: ['唱', '跳', 'rap', '篮球']
console.log(obj1); // {name: '李四', age: 18, hobby: hobby: ['唱', '跳', 'rap', '篮球', '你干嘛']
这种方法可以看出,一层和多层都不会互相收到影响,所以这种一般称之为深拷贝,这种方法一般适用于绝大需求,但如果所要拷贝的数据中含有方法,那这种方法就失效了
const obj = {
name: '张三',
age: 18,
hobby: ['唱', '跳', 'rap', '篮球'],
fun1: () => {
console.log(111);
},
};
const obj1 = JSON.parse(JSON.stringify(obj));
console.log(obj); // {name: '张三', age: 18, hobby: Array(4), fun1: ƒ}
console.log(obj1); // {name: '张三', age: 18, hobby: Array(4)}
方法拷贝不出来
————————————————————————————————————————————————————————
如果数据中真的含有方法,那么最好的办法就是自己写一个深度拷贝的方法了
复制复杂的对象类型:
function deepCopy (data1, data2){
for (var key in data1) {
if (typeof data1[key] === 'object' && data1[key] !== null) {
data2[key] = data1[key].constructor === Array ? [] : {};
deepCopy(data1[key], data2[key]);
} else {
data2[key] = data1[key];
}
}
}
let oldObj = {
val1: ['a','b','c'],
val2: 'name',
val3: {
num1: '123',
num2: 'ddd'
}
}
let newObj = {}
deepCopy(oldObj,newObj);
newObj.val1[0] = 'f';
newObj.val3.num1 = '456';
console.log(oldObj);
console.log(newObj);
// 对比结果,修改新的数据并不会影响旧的数据
复制复杂的数组类型:
function deepCopy (data1, data2){
for (var key in data1) {
if (typeof data1[key] === 'object' && data1[key] !== null) {
data2[key] = data1[key].constructor === Array ? [] : {};
deepCopy(data1[key], data2[key]);
} else {
data2[key] = data1[key];
}
}
}
let oldArr = [{val1: 'name'},{val2: 'age'}]
let newArr = [];
deepCopy(oldArr,newArr);
newArr[1].val2 = 'aaa';
console.log(oldArr);
console.log(newArr);
// 对比结果,修改新的数据同样不会影响旧的数据