深拷贝解决了什么问题?
在 JavaScript 中的数据类型分为基本数据类型和引用数据类型,基本数据类型的值存储在栈中,变量存储的是值,而引用数据类型的值存储在堆中,变量存储的是值在堆中的引用地址。
对于赋值操作(let b = a),分为两种情况:
- 如果 a 为基本数据类型,则直接将 a 在栈中的值复制一份给 b,后续再对 a 进行改值操作,不会影响到 b 的值
- 如果 a 为引用数据类型,则会将 a 存储的引用地址复制给 b ,此时相当于 a 和 b 的值同时依赖于该引用地址在堆内存中所代表的的值,无论是 a 或是 b 对该引用地址的值进行操作,都会影响到另一个变量。
如果现在有一个变量为 obj1 和另一个变量 obj2 ,obj1 的数据类型为对象,需要将 obj1 的值“拷贝”一份到 obj2 中,且改变其中任意一个变量的值都不能影响到另外一个对象,该“拷贝”操作则被称为深拷贝。
深拷贝的方法
在以下方法钟,original 表示被拷贝的对象(源对象),target 表示拷贝到的对象(目标对象)。
-
通过 ES6 新加入的拓展运算符
let target = {...original}注意:源对象中不能包含对象类型参数。
-
通过
Object.assign对象let target = Object.assign({},original)注意:源对象中不能包含对象类型参数。
-
通过
JSON.parse和JSON.stringify
let target = JSON.parse(JSON.stringify(original))
注意:源对象中不能有如下类型:Date, functions, undefined, Infinity, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays
- 自定义函数
function deepClone(target,original) {
for(let k in original){
if(typeof original[k] === "object"){
target[k] = {}
deepClone(target[k],original[k])
}else{
target[k] = original[k]
}
}
}