一、浅拷贝
拷贝-复制, 将一个对象的属性和方法复制到另一个对象上, 只复制一层,如果属性是对象,只复制对象的地址
- 如下所示:
当改变了旧对象oldObj的属性后,查看新对象和就对象的属性变化
// 旧对象
const oldObj = {
name: '小明',
age: 23,
fun: {
swiming: '游泳'
}
}
// 新对象
const newObj = {};
// 拷贝对象函数
const copyObj = (newObj, oldObj) => {
for (const key in oldObj) {
newObj[key] = oldObj[key];
}
}
copyObj(newObj, oldObj);
oldObj.name = "小红";
oldObj.fun.swiming = "去游泳";
console.log("-----旧对象----");
console.dir(oldObj);
console.log("-----新对象----");
console.dir(newObj);
-
打印结果
当旧对象oldObj的name属性变化后,新对象newObj的name属性不会变化;但是当旧对象oldObj中的fun对象下面的swiming属性变化后,新对象newObj的fun对象下的swiming属性也会变化。
原因是对象是存放在堆里面的,而对象名存放在栈里面的是存放的堆的内存地址,当fun对象copy一份后,并不是把对象拷贝的一份,而是把对象的地址拷贝了一份
二、深拷贝
- 深拷贝是将对象中还存在的对象的属性全部再拷贝一份;
- 在浅拷贝中用循环去拷贝对象,那么在浅拷贝中再套一层循环拷贝就实现了深拷贝;
- 但是如果一个对象中嵌套了多层对象,去拷贝的时候就需要用到递归的方法去实现拷贝
//旧对象
const oldObj = {
name: '小明',
age: 18,
sex: '男',
fun: {
swiming: '游泳',
lookbook: '看书',
}
}
//新对象
const newObj = {}
//拷贝函数
const copyObj = (oldObj, newObj) => {
for (key in oldObj) {
let item = oldObj[key];
if (item instanceof Object) {
newObj[key] = {}; //创建一个新空间
copyObj(item, newObj[key]);
} else {
newObj[key] = oldObj[key]
}
}
}
copyObj(oldObj, newObj);
oldObj.sex = '女';
oldObj.fun.swiming = '象棋'
newObj.fun.lookbook = '读书'
console.dir(oldObj);
console.dir(newObj);
-
打印结果
实现深拷贝以后,无论怎么去改变旧对象中嵌套的对象的属性时,都不会影响到新对象中对应的属性值