浅拷贝与深拷贝
1.数据类型
1.基本数据:直接存储在栈中的数据
2.引用数据:在栈中存储对该对象的引用,真实的数据存放在堆内存中
深浅拷贝只针对Object和Array这样的引用类型,对于基本类型改变的是内容,引用数据类型改变的是地址
2.浅拷贝
只复制指向某对象的指针(引用),而不复制对象本身,新旧对象还是共享同一块内存
1.递归
function copy(obj) {
//创建一个新对象
const objCopy = {}
//遍历对象
for (const key in obj) {
//把原对象中的的每一项赋值给新对象
objCopy[key] = obj[key];
}
//返回新对象
return objCopy;
}
2.Object.assign(newObject,oldObject)
可以对非嵌套对象进行深拷贝,如果对象中出现嵌套情况,那么其被嵌套对象的行为就成了浅拷贝,该方法适用于没有嵌套的情况。
let Person1={name:'jasmine',age:18}
let Person2=Object.assign({},Person1)
Person2.name='xiaosong'
console.log(Person1.name);//xiaosong
3.拓展运算符 newObject={…oldObject}
let Person1={name:'jasmine',age:18}
let Person 2={...Person1}
3.深拷贝
会另外创建一个一模一样的对象,不仅仅对对象的引用进行复制,还会把对象的值一起拷贝,新对象跟原对象不共享内存,深拷贝后的对象和原对象相互独立,其中一个改变对另一个没有影响
1.第三方库 lodash中的deepClone()
使用第三方库是实际工作中实现深拷贝比较常用的方式,lodash中的cloneDeep()
const person1 = {name: "xiao", age: 18};
const person2 = _.cloneDeep(person);
person.name='xiaosong'
console.log(person2.name)//xiao
2.JSON.parse(JSON.stringify(obj))
这个是开发过程中最常用的方式,但是有一个缺陷就是,对于部分数据类型(undefined,function,Symbol),拷贝后的数据会丢失。原理是先把对象转为json字符串,再转为js对象。
let People1={name:"jasmine_songsong",age:19}
let People2=JSON.parse(JSON.stringify(People1));
People2.age=20;
console.log(People1.age)//19
console.log(People2.age)//20
3. 递归拷贝
let People1={name:"jasmine_songsong",age:19}
function deepClone(obj) {
//1.判断是否是对象
if (typeof obj !== 'object' || obj == null)
return obj
//2.判断是否是数组
let newObj;
if (obj instanceof Array) {
newObj = [];
} else {
newObj = {}
}
//3.遍历对象
for (let key in obj) {
//4.避免拷贝原型的属性方法
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
//6.返回深拷贝的结果
return newObj;
}
let person2=deepClone(People1)
Peolple3.name='xiaosong'
console.log(people2)