其实这两个概念真的很简单,但是实际工作中,大多数人依然没有彻彻底底的搞明白他们之间的一些区别。介绍深浅拷贝之前,需要先说说赋值。其实在很多人眼里,包括之前的我也有这个误解,认为浅拷贝和赋值是一样的东西,实际不是的。区别还很大。
首先是一些前置知识:
1、js的一般数据类型是存储在栈中;
2、js的引用类型的数据是存储在堆中;
针对引用数据类型来说 赋值、深拷贝、浅拷贝的区别:
- 赋值:当我们把一个新对赋值给一个新的变量时,赋的其实是改对象的在栈中的地址值,而不是堆中的数据,也就是两个对象指向同一个堆内存空间,无论哪个对象改变,其实都是改变的堆中的数据,因此两个对象其实是联动的。
- 浅拷贝:重新在堆中创建内存,拷贝前后对象的基本数据类型互不影响,但拷贝前后对象的引用数据类型因共享一块内存,会互相影响。进一步说明:浅拷贝是创建一个对象,这个对象有着原始对象属性的一份精确拷贝,如果属性是基本数据类型,拷贝的就是基本类型的值;如果属性是引用数据类型,拷贝的就是内存地址,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
- 深拷贝:从堆内存中开辟一个新的区域存放新对象,对对象中的子对象进行递归拷贝,拷贝前后两个对象互不影响。进一步说明:两个对象完全不相干,各干各的。
浅拷贝的实现方式
-Object.ssign()
-lodash 的 clone()
-...展开运算符
-Array.prototype.contact
-Array.prototype.slice
深拷贝的实现方式
-JSON.parse(JSON.stringfy())
-递归的操作
-lodash cloneDeep()
-Jquery.extend()
实际代码:
注意点 JSON.parse(JSON.stringfy()) 是没法复制function、date、RegExp、null