提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、浅拷贝
浅拷贝:创建一个新对象,将原始对象的属性值精确的拷贝
如果对象属性是基本类型(string,number等)数据,拷贝的就是基本类型的值,此时,改变新对象数据属性,原对象属性不会发生改变
如果对象属性是引用类型(Object)数据,那么就是拷贝的这个对象属性的堆内存地址,如果新对象属性值发生改变,就会影响到原始对象
//定义一个对象
let obj = {
id: 1,
name: '和小灰',
msg: {
age: 10
}
}
// 定义一个对象
let o = {}
// 遍历obj中的属性 将obj中属性的值赋给 o
for (let k in obj) {
o[k] = obj[k];
}
// 改变新对象的某个属性的值
o.msg.age = 1;
//输出原始对象
console.log(obj);
执行结果:
我们可以看出,当我改变 o 中 msg 内的 age 时,原对象 obj 的 msg 的 age 也发生改变
当我改变的是 id 时
o.id = 2;
console.log(o);
//输出原始对象
console.log(obj);
执行结果
所以,浅拷贝对引用类型数据拷贝的是它的地址
顺便说哈浅拷贝可以用
Object.assign(新对象,原对象)
二、深拷贝
深拷贝:创建一个新对象,将原始对象从内存中完整的拷贝出来
从堆内存中开辟出一个新的区域存放新对象,且修改新对象,不会影响原始对象
简而言之就是所有属性一个一个的拷贝
// 深拷贝拷贝多层, 每一级别的数据都会拷贝.
var obj1 = {
id: 1,
name: '和小灰',
msg: {
age: 18
},
color: ['pink', 'red']
};
var o1 = {};
// 封装函数
function deepCopy(newobj, oldobj) {
for (let k in oldobj) {
let item = oldobj[k];
if (item instanceof Array) {
newobj[k] = [];
deepCopy(newobj[k], item);
}
if (item instanceof Object) {
newobj[k] = {};
deepCopy(newobj[k], item);
} else {
newobj[k] = item;
}
}
}
deepCopy(o1, obj1);
console.log(o1);
// 改变新对象的引用类型数据值
o1.msg.age = 20;
console.log(obj1);
执行结果
改变了新对象中的 msg 的 age,原对象并没有随之而变
三、总结
浅拷贝拷贝引用类型时拷贝的是所指向地址
深拷贝则是开辟一个新空间存储新对象,在改变新对象时不会影响原对象