深拷贝和浅拷贝
JS的变量分为基本类型和引用类型,基本类型存储在栈中,而引用类型实际对象存储在堆内存中,栈中保存着对象在堆内存的地址。一般我们对引用类型变量做浅拷贝(obj1 = obj2),只能复制栈中的内存地址给新对象,指向的仍是同一片内存区域,一旦修改摸一个对象另一个对象也会被改变。深度拷贝是相对于浅拷贝而言的,是另外开辟出一个内存空间存储另一个一模一样的引用对象。深拷贝和浅拷贝都是针对引用变量而言的,基本变量没有这个概念。
深拷贝的几种实现方式
1.JSON
Json.parse(Json.stringify(oldObj))
这个方法能处理的对象属性只能是Number、Array、Boolean、String等能被Json表示的数据结构,对于RegExp、function、undefined、symbol等属性在转换过程中就会被忽略。
2.递归拷贝
function deepCopy(obj) {
var result = Array.isArray(obj)? [] : {}
// for...in 遍历对象自身和继承的所有可枚举属性
// hasOwnProperty判断对象自身是否有该属性,我们只拷贝对象自身的属性
for(let key in obj) {
if (obj.hasOwnProperty(key)) {
if(typeof obj[key] === 'Object') {
result[key] = deepCopy(obj[key])
} else {
result[key] = obj[key]
}
}
}
return result
}
//或者这样遍历复制
Object.keys(obj).forEach((key) => {
if(typeof obj[key] === 'Object') {
result[key] = deepCopy(obj[key])
} else {
result[key] = obj[key]
}
})
3.Object.assign
这时ES6中的一个新方法,用来将源对象的可枚举属性复制给新对象
Object.assign({}, source)
但是这个方法只能复制一层属性,对于嵌套对象不能实现真正的深层拷贝