深拷贝与浅拷贝

原文地址:https://www.cnblogs.com/imdeveloper/p/11941754.html

深拷贝与浅拷贝的区别

之所以会有深拷贝与浅拷贝之分,是因为不同数据类型的数据在内存中的存储区域不一样。

简单来说,假设B复制了A,当修改A时,看B是否会发生变化:如果B也跟着变了,说明这是浅拷贝;如果B没变,那就是深拷贝。

相关名词解释:堆栈,基本数据类型与引用数据类型

堆栈

堆和栈是计算机中划分出来用来存储的区域,其中堆(heap)则是动态分配的内存,大小不定也不会自动释放;而栈(stack)为自动分配的内存空间,它由系统自动释放。存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问。

基本数据类型

  1. 基本数据类型有:number、string、boolean、null、undefined五类(数据的原始值是大小确定不可变的,所以放在栈内存中)
  2. 基本类型的变量名和变量值都存储在栈内存中,当B复制A时,栈内存会新开辟一个内存,所以修改A对B无影响(算不上深拷贝,因为深拷贝这个概念是针对较为复杂的object类型数据)

引用数据类型

  1. 引用数据类型(Object类)有常规名值对的无序对象{a:1}、 数组[1,2,3]、以及函数等(类对象
  2. 引用数据类型的“变量”名存在栈内存中,“变量”值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值。当B对A进行简单拷贝时,其实复制的是A的引用地址,而并非堆里面的值。由于A和B指向的是同一个地址,所以修改A时B也受了影响,这就是所谓的浅拷贝

引用类型比较与基本类型变量之间相比较的区别

  1. 引用类型是引用的比较(两个独立的数组,即使包含的值完全相同,用==比较也会得到false)
  2. 基本类型间的比较是值的比较

几种“拷贝”的区别

赋值

引用类型的赋值,因为赋值操作只相当于是引用,两个变量还是指向同一对象,任何一方改变了都会影响到另一方

浅拷贝

对被拷贝对象的外层属性进行了复制,但对象的子类对象地址依然指向堆上的同一块内存地址

深拷贝

把对象以及对象的子对象进行拷贝,并在堆内存中也开辟一个新的内存专门为复制生成的B存放值(就像基本类型那样),就达到深拷贝的效果了

深拷贝的几种实现思路:

  1. 递归去复制所有层级属性;
  2. JS中使用JSON.stringify()和JSON.parse();
  3. Java中使用ObjectInputStream、ObjectOutputStream序列化对象再反序列化。

开发中的实际使用

例如后台返回了一堆数据,需要对这堆数据做操作,但多人开发情况下,是没办法明确这堆数据是否有其它功能也需要使用,直接修改可能会造成隐性问题,深拷贝能更安全安心的去操作数据。

原文地址:https://www.cnblogs.com/imdeveloper/p/11941754.html