我们在对对象进行复制时就用到深浅拷贝。
一、普通复制
<script>
const people={
name:'tim',
age:22
}
const test=people;
console.log(test);//tim 22
test.age=20;
console.log(test);//tim 20
console.log(people);//tim 20
</script>
控制台打印结果:
之所以我们要用到拷贝,是因为直接赋值的复制可能不能满足我们的需求。向上面代码所展示的,我们复制代码时,复制到的是地址,所以对复制体修改实际修改的是原对象的值,这个时候我们再对对象进行复制的意义就不大了。
二、浅拷贝
浅拷贝是创建一个新的对象,但只复制原对象的第一层属性,如果原对象的属性是基本类型,那么复制的是值,在对复制体进行更改不会改变原对象的值;如果原对象的属性是引用类型,那么复制的是地址,复制的对象改变改变的就是地址里的内容,原对象内容也会改变。
浅拷贝方法:
- 方法1:Object.assign(目标文件,原文件)
- 方法2:const 目标文件={...原文件}
拷贝数组:
方法1:Array.prototype.concat()
方式2:[...arr]
代码演示:
<script>
const people={
name:'tim',
age:22,
student:{
student:'cc'
}
}
//方法1
//const test= {...people};
//方法2
const test= {};
Object.assign(test,people);
console.log(test);//tim 22 cc
test.age=20;
test.student.student='bb';
console.log(test);//tim 20 bb
console.log(people);//tim 22 bb
</script>
控制台打印结果:
三、深拷贝
深拷贝是创建一个新的对象,并递归地复制原对象的所有层级的属性,无论原对象的属性是基本类型还是引用类型,都会复制其实际的值,深拷贝后两个对象完全独立,互不影响。
深拷贝的方法:
1、递归实现
<script>
const people = {
name: 'tim',
age: 22,
student: {
student: 'cc'
}
}
const test = {};
//拷贝函数
function deepCopy(newObj,oldObj) {
for(let k in oldObj){
if(oldObj[k] instanceof Array){
newObj[k]=[];
deepCopy(newObj[k],oldObj[k]);
}else if(oldObj[k] instanceof Object) {
newObj[k]={};
deepCopy(newObj[k],oldObj[k]);
} else{
newObj[k]=oldObj[k];
}
}
}
deepCopy(test,people);
console.log(test);
test.student.student = 'bb';
console.log(test);
console.log(people);
</script>
2、使用js库lodash里面cloneDeep内部实现
<script src="https://cdn.jsdelivr.net/lodash/4.17.21/lodash.min.js"></script>
<script>
const people = {
name: 'tim',
age: 22,
student: {
student: 'cc'
}
};
const test = _.cloneDeep(people);
console.log(test);
test.student.student = 'bb';
console.log(test);
console.log(people);
</script>
3、利用JOSN字符串转换
<script>
const people = {
name: 'tim',
age: 22,
student: {
student: 'cc'
}
}
//转换为字符串JSON.stringify(people);
//再转换为对象
const test = JSON.parse(JSON.stringify(people));
console.log(test);
test.student.student = 'bb';
console.log(test);
console.log(people);
</script>
控制台打印结果: