浅拷贝与深拷贝
数据结构基本存储结构:线性结构、树形结构、图状结构和集合四种



在js声明变量用到了栈和堆的概念,栈属于顺序结构,堆属于树形结构
基本数据类型:Strint、Number、Bollean、Undefined、Null、Symbol(ES6新增了解) 基本数据类型是一些简单数据,它们存在栈内存中。
引用数据类型:Array、Object 引用数据类型是保存在堆内存中的,在栈内存保存一个对堆内存中的引用(地址),所有javascript引用数据类型
的操作都是操作对象的引用而不是实际的对象。

let obj1 = obj2;
赋值和浅拷贝的区别
当我们把一个对象赋值给一个新的变量时,赋的其实是该对象的在栈中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的。
浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。即默认拷贝构造函数只是对对象进行浅拷贝复制(逐个成员依次拷贝),即只复制对象空间而不复制资源。
浅拷贝与深拷贝区别
深它会创建一个新对象,如果属性是基本类型,拷贝的就是基本类型的值,;如果属性是内存地址(引用类型),会创建一个新的真实数据,这个真实数据和原数据相同。但是地址不同。新对象里存储的是新地址。即连个数据毫无关联。对一个操作不影响另外一个

Object.assign()进行的是浅拷贝但是当object只有一层的时候,是深拷贝
Array.slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组
如果该元素是个对象引用(不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。
对于字符串、数字及布尔值来说(不是 String、Number 或者 Boolean 对象),slice 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。
JSON.parse(JSON.stringify())进行深拷贝,但是不能处理函数。
递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝。
//定义检测数据类型的功能函数
function checkedType(target) {
return Object.prototype.toString.call(target).slice(8, -1)
}
//实现深度克隆---对象/数组
function clone(target) {
//判断拷贝的数据类型
//初始化变量result 成为最终克隆的数据
let result, targetType = checkedType(target)
if (targetType === 'Object') {
result = {}
} else if (targetType === 'Array') {
result = []
} else {
return target
}
//遍历目标数据
for (let i in target) {
//获取遍历数据结构的每一项值。
let value = target[i]
//判断目标结构里的每一值是否存在对象/数组
if (checkedType(value) === 'Object' ||
checkedType(value) === 'Array') { //对象/数组里嵌套了对象/数组
//继续遍历获取到value值
result[i] = clone(value)
} else { //获取到value值是基本的数据类型或者是函数。
result[i] = value;
}
}
return result
}

浙公网安备 33010602011771号