# 什么是浅拷贝
浅拷贝是创建一个新对象,这个新对象的部分属性是原始对象属性的引用。也就是说,新对象和原始对象会共享一部分数据。当原始对象中的某些属性是引用类型(如列表、字典、自定义对象等)时,浅拷贝只复制这些引用类型属性的引用,而不是复制它们本身。这意味着,新对象和原始对象中的这些引用类型属性指向内存中的同一个对象,因此修改其中一个对象的引用类型属性时,另一个对象也会受到影响。
## 基础数据类型
1. number
2. string
3. boolean
4. null
5. undefined
6. sysbom
7. bigInt
## 引用数据类型
1. 对象
2. 数组
3. 方法
4. Date
## 演示下
// 有一个info对象
var info={
name:'张三',
child:{
name:'zhang3'
}
}
console.log('info.name',info.name);//张三
// 把info对象赋值给info2
var info2=info;
// 修改info2的name 会影响到info的name
info2.name='李四';
console.log('info2.name',info2.name); // 李四
//这里打再印info.name值已经被修改了
console.log('info.name',info.name); // 李四
# 常见的浅拷贝
## 使用展开运算符
var info={
name:'张三',
child:{
name:'zhang3'
}
}
// 使用展开运算符进行浅拷贝
var info3={
...info
};
// 修改info3的name 不会影响到info的name
info3.name='王五';
console.log('info3.name',info3.name); // 王五
console.log('info.name',info.name); // 张三
## Obecjt.assgin
var info={
name:'张三',
child:{
name:'zhang3'
}
}
// 使用Obejct.assign进行浅拷贝
var info4=Object.assign({},info);
info4.name='赵六';
console.log('info4.name',info4.name); // 赵六
console.log('info.name',info.name); // 张三
## 数组浅拷贝 slice截取
var list=[1,2,3,4,5];
// 这里使用展开运算符也能够对数组进行浅拷贝
var list2=[...list];
list2[0]=100;
console.log('list2',list2); // [100,2,3,4,5]
console.log('list',list); // [1,2,3,4,5]
// 使用slice进行浅拷贝 不传递参数则默认截取所有。
var list3=list.slice();
// 修改list3的第一个元素
list3[0]=100;
console.log('list3',list3); // [100,2,3,4,5]
console.log('list',list); // [1,2,3,4,5]
## concat拼接数组
`
var list=[1,2,3,4,5];
// 使用concat进行浅拷贝
// concat的参数可以传递一个或多个数组 ,不传参数的时候会返回一个数组的浅拷贝
var list4=list.concat();
// 修改list4的第一个元素
list4[0]=100;
console.log('list4',list4); // [100,2,3,4,5]
console.log('list',list); // [1,2,3,4,5]
// 使用空数组拼接list也能实现一样的效果
var list5=[].concat(list);
// 修改list5的第一个元素
list5[0]=100;
console.log('list5',list5); // [100,2,3,4,5]
console.log('list',list); // [1,2,3,4,5]
# 浅拷贝问题
使用浅拷贝修改的只是对象简单数据类型,当我们修改对象的引用数据类型的时候则还会影响到原来的对象。这里使用展开运算符浅拷贝演示下
// 有一个info对象
var info={
name:'张三',
child:{
name:'zhang3'
}
}
// 浅拷贝复制
var info2={
...info
};
info2.name='李四';
//这里修改了info下面child对象的name属性
info2.child.name='li4';
console.log('info',info); // {name: '张三', child: {name: 'li4'}}
console.log('info2',info2); // {name: '李四', child: {name: 'li4'}}
为了解决这个问题,这里就需要使用到深拷贝了。
# 深拷贝
深拷贝是在处理对象或数组这类引用数据类型时的一种数据复制技术,旨在创建一个与原始对象或数组完全独立的副本,新副本和原数据在内存中占据不同的空间,对新副本的任何修改都不会影响到原始数据。
## JSON.parse JSON.stringify
var info={
name:'张三',
child:{
name:'zhang3'
}
}
// 使用JSON.parse(JSON.stringify(info))进行深拷贝
var info3=JSON.parse(JSON.stringify(info));
info3.name='王五';
//这里的赋值操作不会修改info下面child对象的name属性了
info3.child.name='wang5';
console.log('info',info); // {name: '张三', child: {name: 'zhang3'}}
console.log('info3',info3); // {name: '王五', child: {name: 'wang5'}}
需要注意点是这种方法无法处理函数,sysbom和循环引用的对象。函数,sysbom无法被序列化成json字符串,循环引用的对象则会报错。
# 总结
个人感觉深拷贝和浅拷贝在实际开发中需要运用的场景还是挺多的,end。
(有误欢迎大佬指正)