深浅拷贝
1、什么是深浅拷贝
深浅拷贝都只是针对引用对象来区分的,其他基本类型并不区分什么深浅拷贝。
浅拷贝:
浅拷贝是对内存地址的复制,让目标对象指针和源对象指向同一片内存地址。
当内存销毁的时候,指向对象的指针必须重新定义才能够使用。
深拷贝:
深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后两个对象虽然存的值是一样的,但是内存地址不一样。
2、深浅拷贝的实现
- 浅拷贝实现方式
直接赋值即可实现对象浅拷贝
// 浅拷贝
let obj1 = {
a: 0, b: {
c: 0 } }
let obj2 = obj1
console.log(obj1); // { a: 0, b: { c: 0 } }
console.log(obj2); // { a: 0, b: { c: 0 } }
// 修改obj1中的a属性
obj1.a = 1
// 可以看到obj2中的a属性的值也改变了,这样就能证明obj2只是对obj1对象内存地址的复制,指针还是指向obj1对象内存地址
console.log(obj2); // { a: 1, b: { c: 0 } }
- 深拷贝实现方式:
方式一:JSON.stringify()方法和JSON.parse()方法实现
let obj1 = {
a:0,b:{
c:"hello"}}
let obj2 = JSON.parse(JSON.stringify(obj1))
console.log(obj2); // { a: 0, b: { c: 'hello' } }
obj1.a = 1
console.log(obj1); // { a: 1, b: { c: 'hello' } }
console.log(obj2); // { a: 0, b: { c: 'hello' } }
// 可以看到,obj1的a属性取值改变并不会影响到obj2中的a属性取值,
// 所以也就可以说明这两个对象内存地址并不一样
方式二:通过assign()方法实现(特殊)
关于assign()方法的介绍可以看MDN官方
这个方法比较特殊,当对象嵌套层次小于2层,则是深拷贝,大于等于2层时则是浅拷贝,具体原理:利用拼接原理,对对象进行拼接,将后续对象的内容插入到第一哥参数指定的对象,并且不会修改第一个参数之后的对象。
let obj1 = {
a: 0, b: {
c: "hello" } }
let obj2 = Object.assign({
}, obj1)
obj1.a = 1 // 小于2层的为深拷贝
obj1.b.c = '你好' // 大于等于层的为浅拷贝
console.log(obj1); // { a: 1, b: { c: '你好' } }
console.log(obj2); // { a: 0, b: { c: '你好' } }
方式三:自定义深拷贝(循环实现)
function myDeepClone(Obj) {
var newObj;
if (Obj instanceof Array) {
//确定类型
newObj = []; // 创建一个空的数组
var i = Obj.length;
while (i--) {
newObj[i] = myDeepClone(Obj[i]); //递归回调
}
return newObj; //结束函数完成深拷贝
} else if (Obj instanceof Object) {
//确定类型
newObj = {
}; // 创建一个空对象
for (var k in Obj) {
// 为这个对象添加新的属性
newObj[k] = myDeepClone(Obj[k]); //递归回调
}
return newObj; //结束函数完成深拷贝
} else {
return Obj; //结束函数完成深拷贝
}
}
let obj1 = {
a: 0, b: {
c: "hello" } }
let obj2 = myDeepClone(obj1)
obj1.b.c = "你好"
console.log(obj1); // { a: 0, b: { c: "你好" } }
console.log(obj2); // { a: 0, b: { c: "hello" } }