在很多的案例中我们可能需要用到深拷贝或者浅拷贝,接下来我来说说深拷贝和浅拷贝的区别及其用法。
1.浅拷贝的用法
1.Object.assign()
let obj = {
a: 1,
b: {
c: 2,
},
d: [3, 4],
};
let obj1=Object.assign(obj)
console.log(obj1);
这里输出的结果跟输出obj的输出结果一样
2.ES6展开运算
let obj2={...obj}
这里是先把obj结构然后外边花括号再合并成对象
3.concat
let obj4=[].concat(obj)[0]
这里因为concat是数组的方法,所以先用[]把obj拼劲进数组[]然后取第一项就是obj
2.深拷贝的用法
1.JSON.parse(JSON.stringify())
let obj5=JSON.parse(JSON.stringify(obj))
在这里先是使用转字符串方法转成字符串再使用JSON.parse转为原来对象,这里因为转化为字符串之后就跟原来的对象没有任何的关系了。但是这个方法只支持json能理解的数据格式。
2.自己的方法实现一个
function Copy(obj) {
let result;
if (typeof obj == "object") {
if (Array.isArray(obj)) {
result = [];
for (let i = 0; i <= obj.length - 1; i++) {
result[i] = Copy(obj[i]);
}
} else {
result = {};
for (let key in obj) {
result[key] = Copy(obj[key]);
}
}
} else {
return obj;
}
return result;
}
这里我先是声明一个变量result来接收值,第一部先判断传进来的obj是不是复杂数据类型,当是复杂数据类型的时候我有进行数组判断,判断传进来的是不是一个数组,当是数组的时候我把result的值赋值为[]然后循环数组obj,result的每一项就是obj的每一项,但是因为obj的每一项可能又复杂数据类型的值,所以再次调用函数。当不是数组的时候把result赋值成{}利用对象的循环方法for in 进行循环。当不是复杂数据类型的时候直接返回当前值,最后返回result。
3.深拷贝和浅拷贝的区别
let obj2 = { ...obj };
obj.d.push(5)
当使用解构的方法拷贝了obj之后,改变obj里边的复发数据类型的值,obj2也会跟着改变,这就是浅拷贝
function Copy(obj) {
let result;
if (typeof obj == "object") {
if (Array.isArray(obj)) {
result = [];
for (let i = 0; i <= obj.length - 1; i++) {
result[i] = Copy(obj[i]);
}
} else {
result = {};
for (let key in obj) {
result[key] = Copy(obj[key]);
}
}
} else {
return obj;
}
return result;
}
let obj6 = Copy(obj);
obj.d.push(6);
console.log(obj6);
用这个深拷贝的方法,改变obj的值之后这个深拷贝出来的obj6的值是不会跟着改变的
基本数据类型,拷贝是直接拷贝变量的值,而引用类型拷贝的其实是变量的地址。 而浅拷贝和深拷贝就是在这个基础之上做的区分,如果在拷贝这个对象的时候,只对基本数据类型进行了拷贝,而对引用数据类型只是进行了引用的传递,而没有重新创建一个新的对象,则认为是浅拷贝; 反之,在对引用数据类型进行拷贝的时候,创建了一个新的对象,并且复制其内的成员变量,则认为是深拷贝。