浅拷贝: 创建一个新的对象,去拷贝另一个对象的 属性和属性值。 如果属性值是对象类型,只是把对象的地址拿过来用了。只是拷贝的第一层的属性,第二层用的还是原来的。
深拷贝: 创建一个新的对象,去拷贝另一个对象的 属性和属性值。如果属性值是对象类型,就创建一个新的对象,拷贝这个属性值。依次类推 把对象所有深层次的 属性值都拷贝一遍。
浅拷贝
let zhangsan = {
name: 'zhangsan',
child: {
name: 'zhangsanfeng'
}
};
// 拷贝一个zhangsan对象出来
// let obj2 = {name:zhangsan.name};
let obj2 = {};
obj2.name = zhangsan.name;
obj2.child = zhangsan.child;
console.log(zhangsan);
console.log(obj2);
/*
child:001 {name:'zhangsanfeng'}
zhangsan { name:zhangsan,child:001}
obj2 {name:'zhangsan',child:001}
*/
// obj2 是新创建的对象,地址和zhangsan不一样的
console.log(zhangsan === obj2);//false
console.log(zhangsan.child === obj2.child);//true
// 实现一个浅拷贝函数
// 遍历一个对象的属性名和属性值 添加到 另一个新对象中
function copy(o) {
// 遍历一个o的属性名和属性值 添加到 另一个新对象中
let newObj = {};
for (let key in o) {
let value = o[key];
newObj[key] = value;
// newObj[key] = o[key]
}
return newObj
}
let resObj = copy(zhangsan);
console.log(resObj);
//true
console.log(resObj.child === zhangsan.child);
/*
zhangsan = {
name: 'zhangsan',
child: 002
}
...zhangsan
name: 'zhangsan',
child: 002
*/
// 展开运算符实现 浅拷贝
let obj3 = { ...zhangsan };
console.log(obj3);
console.log(obj3.child == zhangsan.child);
// Object.assign浅拷贝
let obj4 = {}
Object.assign(obj4, zhangsan);
console.log(obj4 === zhangsan);//false
console.log(obj4);
console.log(obj4.child == zhangsan.child);//true
深拷贝
递归实现方法
let obj1 = {
name: 'zhangsan',
child: {
name: 'zhangsanfeng'
}
};
// obj1.child.father = obj1
// console.log(obj1);
let m = new Map() //存的数据,会影响垃圾回收机制
let wm = new WeakMap()// 存的数据 是一种弱引用(不会影响垃圾回收机制)
// wm.set()
// wm.get()
// wm.has()
function deepCopy(obj) {
let newObj = {};
//遍历obj的属性名和属性值 都添加到newObj中,如果属性值是一个对象,做判断,再创建给新对象,把属性值对象key和value添加到 新对象中
for (let key in obj) {
let value = obj[key]
if (typeof value == 'object') {
// 如果是 创建要给新的value ,和 value 一样
// 调用自己
let newValue = deepCopy(value);
newObj[key] = newValue;
} else {
// 如果属性不是对象,就直接存入新对象中
newObj[key] = value;
}
}
return newObj;
}
let resObj = deepCopy(obj1)
console.log(resObj === obj1);
console.log(resObj.child === obj1.child);
其他实现方法
//2-种
// JSON.stringify parse
let obj1 = {
name: 'zhangsan',
child: {
name: 'zhangsanfeng',
}
};
obj1.child.father = obj1
console.log(obj1);
// 循环引用会报错
let str = JSON.stringify(obj1);
console.log(str);
// JSON.parse 内部会创建一个新对象,放字符串里面的属性名和属性值
let obj2 = JSON.parse(str);
console.log(obj2);
console.log(obj2 == obj1);
console.log(obj2.child == obj1.child);
// 缺点:json数据的类型 有限制--不能存函数
// 如果拷贝的对象 存在循环引用 就会报错
判断深浅拷贝的方法
let obj1 = {
name: 'zhangsan',
child: {
name: 'zhangsanfeng',
// father:
}
};
obj1.child.father = obj1
console.log(obj1);
let obj2 = _.clone(obj1);
console.log(obj2);
// 说明是拷贝
console.log(obj2 === obj1);//false
// 说明是浅拷贝
console.log(obj2.child === obj1.child);//true
let obj3 = _.cloneDeep(obj1);
console.log(obj3);//
// 说明是拷贝
console.log(obj3 === obj1);//false
// 说明是深拷贝
console.log(obj3.child === obj1.child);//false