深拷⻉ 浅拷⻉
⾸先说下堆栈,基本数据类型与引⽤数据类型,深拷⻉与浅拷⻉与此相关。
⼀、基本数据类型 和 引⽤数据类型
1.变量类型分为两类: 基本数据类型: number , string , boolean , null , undefined , symbol
引⽤数据类型:统称为 Object 类型,细分的话,有: Object , Array , Date , Functi
on 等。
2.存储⽅式:
a.基本数据类型保存在 栈 内存,形式如下:栈内存中分别存储着变量的标识符以及变量的 值。例:
let a = 'A';
b.引⽤数据类型保存在 栈 内存,形式如下:名存在栈内存中,值存在于堆内存中,但是栈内 存会提供⼀个引⽤的地址指向堆内存中的值。
例:
let a = {
name:“A”};
3.不同类型的复制⽅式:
a.基本数据类型:
let a = 1;
当你let b = a 时,栈内存会新开辟⼀个内存,例如这样:
此时改变 a 变量的值,并不会影响 b 的值。
b.引⽤数据类型:
let a = {
name: 'A',age: 10};
let b = a;
a.age = 20;
// 此时改变a的值,会改变b的值,此时内存中是这样的:
⼆、浅拷⻉ 和 深拷⻉
浅拷⻉ :创建⼀个新的数据,这个数据有着原始数据属性值的⼀份精确拷⻉。如果属性是基 本类型,拷⻉的就是基本类型的值,如果属性是引⽤类型,拷⻉的就是内存地址,所以如果其 中⼀个数据改变了这个地址,就会影响到另⼀个数据。
可以说 浅拷⻉ 只解决了数据第⼀层的问题,拷⻉第⼀层的基本类型值,以及第⼀层的引⽤类型地址
深拷⻉ :深拷⻉会拷⻉所有的属性,并拷⻉属性指向的动态分配的内存。当对象和它所引⽤ 的对象⼀起拷⻉时即发⽣深拷⻉。深拷⻉相⽐于浅拷⻉速度较慢并且花销较⼤。在堆中重新分 配内存,拥有不同的地址,且值是⼀样的,复制后的对象与原来的对象是完全隔离,互不影响。
三、实现深拷⻉
1.数据只有⼀层的时候: Object.assign() ⽅法可以把任意多个的源对象⾃身的可枚举属性 拷⻉给⽬标对象,然后返回⽬标对象。但是 Object.assign() 进⾏的是浅拷⻉,拷⻉的是 对象的属性的引⽤,⽽不是对象本身。当数据只有⼀层的时候,是深拷⻉。
相同的还有数组⽅法 slice 、 concat ,他们都为浅拷⻉,当数据只有⼀层的时候,可实现深 拷⻉的效果
例:
let a=[