深拷贝与浅拷贝的深入理解

Posted by tree on 2018-03-01

深拷贝与浅拷贝的深入理解

变量在内存中的存储

var a = 1
在栈区中
a 1

基本数据类型:基本数据类型值指保存在栈内存中的简单数据段,访问方式是按值访问。

a = 2
在栈区中
a 2

操作的是变量实际保存的值。

var b = a
在栈区中
a 2
b 2
b = 3
在栈区中
a 2
b 3

引用类型变量在内存中的存储

引用类型变量的复制:复制的是存储在栈中的指针,将指针复制到栈中未新变量分配的空间中,而这个指针副本和原指针指向存储在堆中的同一个对象;复制操作结束后,两个变量实际上将引用同一个对象。因此,在使用时,改变其中的一个变量的值,将影响另一个变量。

   var a = {}
   a.name = john
   var b = a
   b.sex = man

a的值为{name:'john',sex:man}

堆&栈

两者都是存放临时数据的地方。

栈是先进后出的,就像一个桶,后进去的先出来,它下面本来有的东西要等其他出来之后才能出来。
堆是在程序运行时,而不是在程序编译时,申请某个大小的内存空间。即动态分配内存,对其访问和对一般内存的访问没有区别。对于堆,我们可以随心所欲的进行增加变量和删除变量,不用遵循次序。
栈区(stack) 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
堆区(heap) 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
堆(数据结构):堆可以被看成是一棵树,如:堆排序;
栈(数据结构):一种先进后出的数据结构。

引用类型比如对象储存在堆中

浅拷贝

之前变量在内存中的存储就等于浅拷贝,但是还有一种特殊情况

源对象拷贝实例,其属性对象拷贝引用。

var a = [{c:1}, {d:2}];
var b = a.slice();
console.log(a === b); // 输出false,说明外层数组拷贝的是实例
a[0].c = 3;
console.log(b[0].c); // 输出 3,说明其元素拷贝的是引用

深拷贝

深拷贝后,两个对象,包括其内部的元素互不干扰。常见方法有JSON.parse(),JSON.stringify(),lodash的.cloneDeep和.clone(value, true)