🎈浅拷贝和深拷贝快快现出原形~

90 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情

🎈大家好,我是橙橙子,新人初来乍到,请多多关照~

📝小小的前端一枚,分享一些日常的学习和项目实战总结~

😜如果本文对你有帮助的话,帮忙点点赞呀!ღ( ´・ᴗ・` )比心~

基本概念

  • 浅拷贝:只是拷贝数据的内存地址,修改拷贝后的对象,会改变拷贝前的对象
  • 深拷贝:在内存中开辟一个新的存储空间,修改拷贝后的对象,不会改变拷贝前的对象

不论是基本数据类型number,string,boolean还是引用类型object,array都存储在内存中。

而内存又分为栈内存和堆内存。

基本数据类型名字和值都会存储到栈内存中。

引用数据类型名字存储到栈中,值存储到堆内存中。

浅拷贝

复制了对象(数组)存储在栈内存中的地址,而不是在内存中重新开辟一个新的空间。所以两个对象共用一个内容。

let obj1 = {
    a: 1,
    b: 2
}
console.log(obj1); // 输出{a:1, b:2}

let obj2 = obj_1; // 浅拷贝
console.log(obj2); // 输出{a:1, b:2}

obj1.a = 66;
console.log(obj2); // 输出为{a:10, b:2}

obj2拷贝了obj1在栈内存中的地址。所以obj2和obj1共用存储在堆内存的数据。所以,当obj2改变的时候,obj1也就随之改变。 1.ES6的 Object.assign(target, ...sources) target:目标对象。
sources:任意多个源对象。
返回值:目标对象会被返回。

const target = {  };
const source = { b: 4, c: 5 };
const finnalTarget = Object.assign(target, source);
console.log(target);
console.log(finnalTarget);
source.b = 6;
console.log(source)
console.log(target)

image.png 扩展运算符

let outObj = { inObj: {a: 1, b: 2} } 
let newObj = {...outObj} 
newObj.inObj.a = 2 
console.log(outObj) // {inObj: {a: 2, b: 2}}

深拷贝

深拷贝会在内存中重新开辟一个新的存储空间。使得两个对象(数组)指向两个不同的堆内存数据。从而实现改变互不影响。

JSON.parse(JSON.stringify(obj))

let obj1 = {
    a:1,
    b:2
}
console.log(obj1); // 输出{a:1,b:2}

let obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj2); // 输出{a:1,b:2}

obj1.a = 10;
console.log(obj2); // 输出依然为{a:1,b:2} 

obj2是obj1的深拷贝对象,所以obj2不会随着obj1的改变而改变

这个方法的坏处就是会丢弃对象的constructor。深拷贝之后,不管原来的构造函数是什么,深拷贝之后都会变成Object。 注意点:

当内部的值为undefined时,不会返回正常结果,只会报错

当转换的对象为空字符串的时候,最后结果也是空字符串

总结

  1. 深拷贝和浅拷贝的概念只针对复杂数据类型。
  2. 深拷贝可以通过JSON的stringify方法和parse方法进行
  3. 浅拷贝是只拷贝复杂数据类型的在栈内存中的地址。本质上两个对象(数组)指向的还是同一块堆内存数据空间
  4. 深拷贝会在堆内存中重新生成一块新的存储空间实现完全的对象(数组)复制