一、浅拷贝
浅拷贝只是拷贝一层(基本数据类型),更深层次级别(引用数据类型)的只拷贝引用。
下面将从一个例子来介绍浅拷贝
var obj = {
id:1,
name:'anni'
msg:{ //mag 是一个对象,属于更深层次的拷贝
age:18
}
};
var obj2 = {};
for(var k in obj){
obj2[k] = obj[k]; //k是属性名,obj[k]是属性值
}
console.log(obj2);
当你将obj2的值赋值给obj 时,基本数据类型【简单地说包括string. boolean. null. number. undefind. sumbol(es6). bigInt(es10)】中的值不会改变,因为obj2 [k]= obj[k] ,栈内会新开辟一个内存。
对于引用数据类型【(object. list. function)】,其实赋的不是值,而是地址,这个地址指向原堆内存的值。所以只要堆内的值一变,所有的值都会改变,
测试一下年龄属性中的值和姓名值是否改变
obj2.name = 'tony';
obj2.msg.age = 20;
console.log(obj);
由结果得到引用数据类型内的年龄值确实变化,而基本数据类型的姓名值未更改。
二、深拷贝
深拷贝拷贝多层,每一级别的数据都会拷贝,以递归方式使用for … in 方法来实现深拷贝。
var obj = {
id:1,
name:'anni',
msg: {
age:18
},
color:['pink','blue']
};
var obj2 = {};
//封装函数
function deepCopy(newobj,oldobj){
for(var k in oldobj){
//判断我们的属性值属于那种数据类型
//1. 获取属性值 oldobj[k]
var item = oldobj[k];
//2. 判断这个值是否为数组
if(item instanceof Array){
newobj[k] = [];
deepCopy(newobj[k],item)
}else if(item instanceof Object){
//3. 判断这个值是否有对象
newobj[k] = {};
deepCopy(newobj[k],item)
}else {
//4. 属于简单数据类型
newobj[k] = item;
}
}
}
deepCopy(obj2,obj)
console.log(obj2);
判断是否影响对象里的值
obj2.msg.age = 20;
console.log(obj);
由打印结果可以看出,改变obj2中的属性值,并不会影响obj中的值,这是因为深拷贝中只会将复制的一份数据重新给obj2,并不影响obj 的原数据。