手写深拷贝

为什么需要深拷贝

前端很多时候都会听到深拷贝,有深就有浅,深拷贝浅拷贝区别在哪,我们为什么要使用深拷贝?什么场景要使用深拷贝?接下来就进行详细分析;

深浅拷贝的区别

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。

但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

所以在实际业务场景中,需要修改原始数据并且要保留原始数据的完整性,就需要用到深拷贝

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
* @description: 判断数据类型
* @param {any} data
* @return {String} 数据类型
*/
const DataType = (data) => {
let str = Object.prototype.toString.call(data)
str = str.replaceAll('[', '').replaceAll(']', '').split(' ')[1].toLowerCase()
return str
}

/**
* @description: 深克隆
* @param {any} original: 原始数据
* @param {*} hashMap: 哈希map
* @return {any} 深克隆后的数据
*/
const CloneDeep = (original, hashMap = new WeakMap()) => {
const type = DataType(original)

if (!['object', 'array'].includes(type)) {
return original
}

let res = (type === 'object') ? {} : []

if (hashMap.has(original)) {
return hashMap.get(original)
}

hashMap.set(original, res)

for (let k in original) {
if (Object.hasOwn(original, k)) {
res[k] = CloneDeep(original[k], hashMap)
}
}

return res
}

讲解

DataType方法,其实就是利用Object.prototype.toString来准确地判断数据类型,详见之前的文章:点击查看

CloneDeep方法,其实就是要深克隆ObjectArray,将数据遍历,进行递归,直到一层层拆解完;

为什么CloneDeep方法中有hashMap?因为某些情况下可能有重复项,利用Map结构保证唯一性;

既然用到Map结构,为什么要用WeakMap,和普通的Map区别在哪里,大家可以自己查证思考下。

最后

已将深拷贝方法发布到 githubnpm ~


手写深拷贝
https://liujiaweb.cn/posts/28238.html
作者
Liu Jia
发布于
2020年8月13日
许可协议