- 了解深拷贝浅拷贝
- 代码中的深拷贝浅拷贝
- 拷贝的实现方法
一、了解深拷贝浅拷贝
1.1 深拷贝(值拷贝)
会创建一个一模一样的对象,新旧对象不共享内存,修改新对象不会影响原对象
。
1.2 浅拷贝(引用拷贝)
只复制指向某个对象的指针,不复制对象本身,新旧对象还是共享同一块内存。修改新对象会影响原对象
。
1.3 区别
在拷贝基本数据类型的时候其实是不区分深拷贝与浅拷贝的,因为都是拷贝原始数据类型的值。
当拷贝的是引用数据类型的时候,则区分浅拷贝、深拷贝,因为浅拷贝只复制引用数据类型的第一层属性,深拷贝可以对引用数据类型的属性进行递归复制。
二、代码中的深拷贝浅拷贝
js中的数据类型:
- 基本数据类型:字符串(string)、数值(number)、布尔值(boolean)、undefined、null ;
- 引用数据类型:对象(Object)、数组(Array)、函数(Function);
对基本数据类型进行复制,并重新赋值,并不会影响到原来的变量,这就是深拷贝。
let myname = '大华';
let age = myname;
age = 22;
console.log(myname); //大华
console.log(age); //22
myname
这个变量会在内存中开辟一个地址,存储一个值为大华
,age
这个变量复制了myname
所以他们指向的都是同一个地址,同时也指向同一个值,但对 age
重新赋值时,会在内存在开辟一个地址来存储另一个值22
。
对引用数据类型进行复制,并重新赋值,会影响到原来的变量,这就是浅拷贝。
let obj1 = {
myname: "大华",
age: 12
}
let obj2 = obj1;
obj2.age = 22;
//里面的age都变成22
console.log(obj1);
console.log(obj2);
对于引用数据类型来说,就有了堆
和栈
的说法,obj1
会开辟一个内存地址,与值相对应(这就是栈),但这个内存地址的值又会被分配到另一个地址,在另一个地址中又创建了对应的值(也就是堆),obj2
在进行复制时,就会通过栈一路找到堆进行复制,一旦修改,那么obj1
和obj2
都会受影响,因为它们指向的都是同一个地址。
三、拷贝的实现方法
实际的项目开发过程中,在多数情况下不希望将对象进行浅拷贝,因为值会相互影响,容易出错,可以把浅拷贝转换成深拷贝。
3.1 深拷贝的实现方法
1、JSON.stringify()
JSON.parse(JSON.stringify(obj)) 是目前比较常用的深拷贝方法之一,它的原理就是利用 JSON.stringify 将 js 对象序列化(JSON字符串),再使用 JSON.parse 来反序列化(还原) js 对象。
这个方法可以简单粗暴的实现深拷贝,但是还存在问题,拷贝的对象中如果有函数,undefined,symbol,当使用过 JSON.stringify() 进行处理之后,都会消失。
let obj1 = {
a: 0,b: {
c: 0}};
let obj2 = JSON.parse(JSON.stringify