首先,在提及浅拷贝与深拷贝的区别时。我们应该知道深拷贝与浅拷贝是针对对象的,因为基本数据类型在进行赋值操作时(也就是拷贝)是直接将值赋给了新的变量,也就是该变量是原变量的一个副本,这个时候你修改两者中的任何一个的值都不会影响另一个,而对于对象或者引用数据来说在进行浅拷贝时,只是将对象的引用复制了一份,也就内存地址,即两个不同的变量指向了同一个内存地址,那么在改变任一个变量的值都是该变这个内存地址的所存储的值,所以两个变量的值都会改变。
浅拷贝:浅拷贝只是拷贝一层,更深层次的对象级别的只拷贝引用
下面我创建了两个对象,其中一个空对象作为我浅拷贝的对象,我们通过遍历对象的方法将obj中的属性与值拷贝到了对象o中,但是随着我们对obj中数据的更改,我们发现o中的值也同样发生了改变,由此可以看出浅拷贝只是将对象的引用复制了一份,也就内存地址,即两个不同的变量指向了同一个内存地址,那么在改变任一个变量的值都是该变这个内存地址的所存储的值,所以两个变量的值都会改变
let obj = {
name: 'xiaomin',
id: 1,
msg: {
age: 18,
},
};
let o = {};
for (let k in obj) {
//k是属性名 ,obj[k] 是属性值
o[k] = obj[k];
}
obj.msg.age = 20;
console.log(o);
console.log(obj);
浅拷贝在es6中的新方法: Object.assign(你要拷贝的对象,等待被拷贝的对象);
这种方法比较方便简洁,但是不会改变浅拷贝的本质
Object.assign(o, obj);
console.log(o);
深拷贝:拷贝多层,每一级别的数据都能拷贝
创建的对象的属性中包含数组与对象
let obj = {
name: 'cc',
age: 17,
color: ['red', 'pink', 'blue'],
msg: {
name: 'dog',
}
}
let oo = {};
封装深拷贝函数
function deepCopy(newobj, oldobj) {
for (let k in oldobj) {
//判断我们的属性属于哪种数据类型
//获取属性值
let item = oldobj[k];
//判断是否是数组
if (item instanceof Array) {
newobj[k] = [];
deepCopy(newobj[k], item)
} else if (item instanceof Object) {
//判断是否是对象
newobj[k] = {};
deepCopy(newobj[k], item)
} else {
newobj[k] = item;
}
}
}
deepCopy(oo, obj);
console.log(oo);
1、JSON.stringify()
JSON.parse(JSON.stringify(obj))是目前比较常用的深拷贝方法之一,它的原理就是利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象。 这个方法可以简单粗暴的实现深拷贝,但是还存在问题,拷贝的对象中如果有函数,undefined,symbol,当使用过JSON.stringify()进行处理之后,都会消失。
let obj1 = { a: 0,b: {c: 0}};
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.a = 1;
obj1.b.c = 1;
console.log(obj1); // {a: 1, b: {c: 1}}
console.log(obj2); // {a: 0, b: {c: 0}}