所谓的浅拷贝和深拷贝:浅拷贝是在在拷贝过程中,遍历时那部分为对象/数组类型指向原来的地址,而深拷贝,则是完全开辟新的内存地址。
浅拷贝和深拷贝都是只针对于像 Object,Array这样的复杂对象。
默认情况下基本数据类型(number,string,null,undefined,boolean)都是深拷贝。
基本数据类型
基本数据类型,直接用等号赋值,也都是深拷贝
let a = 1;
let b = a;
b = 2;
console.log(a,b); //打印出:1,2
b的数值改变并不会影响a,所以基本数据类型赋值就是深拷贝;
引用类型
引用类型,直接用等号赋值,是浅拷贝;
//对象
let a = {
name: 'yinol'
};
let b = a;
b.name = 'yinol111';
console.log(a);
打印结果:a的数据被b改变,拷贝的时候并没有给b创造独立的内存,只是把a指向数据的 指针 拷贝给了b。
//数组
let arr = [1, 2, 3, [4, 5], {a: 6, b: 7}];
let arr2 = arr;
arr2[1] = 999;
console.log(arr); //[1, 999, 3, [4, 5], {a: 6, b: 7}]
ES6 解构赋值
//对象
const a = {
name: 'name',
age: 18,
marriage: false,
}
let { name, age, marriage} = a;
name = 'name1';
age = 20;
marriage = true;
console.log(a)
打印结果:
a的数据并没有被改变,解构赋值好像是深拷贝啊?????看下一个例子
const a = {
name: 'name',
age: 18,
marriage: false,
addr: { province: 'yunnan', city: 'kunming' }
}
let { name, age, marriage, addr } = a
name = 'myname'
age = 26
marriage = true
addr.province = 'shanghai'
addr.city = 'shanghai'
console.log(name, age, marriage, addr)
console.log(a)
解构赋值出来的对象将原对象a中的addr的数据修改了
let arr = [1, 2, 3, [4, 5], {a: 6, b: 7}];
let arr3 = [...arr];
arr[3][0]= -999;
console.log(arr);
总结:
解构赋值,如果所解构的原对象是一维数组或对象,其本质就是对基本数据类型进行等号赋值,那它就是深拷贝;
如果是多维数组或对象,其本质就是对引用类型数据进项等号赋值,那它就是浅拷贝;
解构赋值是浅拷贝(因为它确实不能对多维数组或对象达到深拷贝的作用)
深拷贝的方法
递归自定义函数实现深拷贝
要求对象中的属性值不能是函数、undefined以及symbol值
function deepCopy (obj) {
// 创建一个新对象
let result = {};
temp = null;
key = null;
let keys = Object.keys(obj);
keys.map((item, index) => {
key = item;
temp = obj[key];
// 如果字段的值也是一个对象则递归操作
if (temp && typeof temp === 'object') {
result[key] = deepCopy(temp)
} else {
result[key] = temp
}
});
return result
}
let obj1 = {
x: {
a: 1
},
y: undefined,
z: function test (c, d) {
return c+d
},
u: Symbol('test')
};
let obj2 = deepCopy(obj1);
obj2.x.a = 3;
console.log(obj1);
console.log(obj2);
利用lodash库的cloneDeep方法实现深拷贝
无法拷贝对象原型链上的属性和方法
var arr=[{a:1,b:2},{c:1,d:2}];
var arr2=_.cloneDeep(arr);
arr2[1].d=7;
console.log(arr,arr2);
JSON.parse(JSON.stringify(objectToClone)) 实现深拷贝
var arr=[{a:1,b:2},{c:1,d:2}];
var arr2=JSON.parse(JSON.stringify(arr));
arr2[1].d=7;
console.log(arr,arr2);