1、浅拷贝:浅拷贝就是增加了一个指向已存在的内存,浅拷贝只是拷贝了内存地址,子类的属性指向的是父类属性的内存地址,当子类的属性修改后,父类的属性也随之被修改。
const a = { name: '小寿司', age: 20 }
const b = a
console.log(a, b)
b.name = '小土豆' // 虽然我改的是b中的name,但由于公用同一个地址,a中的name也会改变
console.log(a, b)
a.name = '小葡萄' // 下面同理,我改的是a.name,但是b.name也会变
console.log(a, b)
2.深拷贝 :深拷贝就是增加一个指针,并申请一个新的内存,并且让这个新增加的指针指向这个新的内存地址使用深拷贝,在释放内存的时候就不会像浅拷贝一样出现释放同一段内存的错误,当我们需要复制原对象但有不能修改原对象的时候,深拷贝就是一个,也是唯一的选择。
大白话:拷贝后新的对象跟原来的对象的关系是克隆羊与羊之间的关系,是两个长得一样的两个个体,它两可没有量子纠缠哦,比如克隆羊被剃了羊毛,原来的羊毛还在呢
下面是纯js写的深拷贝
// 这个拷贝函数参数可以是多级对象,也可以是多维数组
function deepClone(old) {
const newObj = Array.isArray(old) ? [] : {}
// 判断old是否是数组,如果是则newObj等于一个空数组,否则等于空对象
// 我们要将old的对象所有属性遍历一遍,然后一个个赋值给新对象
for(let key in old) {
if(typeof old[key] === 'object'){
// 多层对象的处理位置
// 这里复杂数据类型的处理部分(只分为数组和对象)
newObj[key] = deepClone(old[key]);
}else{
// 这样是浅拷贝,所有要对属性值进行判断,看是复杂数据类型还是普通数据类型
// console.log(key,old[key]); //old.key obj[变量]
newObj[key] = old[key];
// newObj.address = old.address; 值是复杂数据类型的时候拷贝的是地址,还是浅拷贝
}
}
return newObj
}
const o1 = { name: '张三',address:{province:'北京'}}
const newObj = deepClone(o1)
newObj.name = '修改'
newObj.address.province = '修改'
console.log(newObj,o1);
这样写是不是有点麻烦哈哈,所有我们有一个非常简单的办法,不过刚开始学习还是要掌握纯js代码的深拷贝哦
工作中深拷贝使用的 是第三方库 lodash(工具函数库)
引入lodash以后,会自动给window上面添加一个变量 _
使用方法如下:
<script src="./lodash.min.js"></script> // 首先要引入对应的文件
const old = { name:'张珊',age:3,address:{province:'北京'},codo:[1,2,3]}
const newObj = _.cloneDeep(old)
console.log(newObj === old);
还有一种方法:使用JSON.stringify() 和JSON.parse()实现深拷贝
const old = { name:'张珊',address:{province:123},code:[1,2,3]}
// JSON.stringify --- 将对象转换为 json字符串
console.log(JSON.stringify(old));
// 将json字符串 转换为对象
console.log(JSON.parse(JSON.stringify(old)));
const newObj = JSON.parse(JSON.stringify(old))
newObj.address.province = '修改后'
console.log(newObj,old);
控制台的打印结果