内容来源:99%的前端都不知道的lodash深拷贝的'BUG' - 掘金 (juejin.cn)
问题代码
import { cloneDeep } from 'lodash' const priceList = [1, 2] const animals = { priceList } const option = { series: ['dog', 'cat'].map(item => animals) } const o = cloneDeep(option) o.series[0].priceList[0] = 5 console.log('o: ', o)
打印结果
深拷贝失效了
在这里我们可以看到,事实上我们只改了series第一个数组里面 priceList里面的值,但是下面series[1].priceList[0]的值也发生了改变变成了5
显然lodash的深拷贝失效了
探索loadsh源码
因为内部源码太长,我将核心内容用伪代码的形式展现 const deepCopy = (data, map = new WeakMap()) => { if (typeof data !== 'object') { return data } if (map.get(data)) { return map.get(data) } const copy = new data.constructor() map.set(data, copy) for (let key in data) { if (data.hasOwnProperty(key)) { copy[key] = deepCopy(data[key], map) } } return copy }
这段代码细看通过 map.get,map.set 解决了对象循环引用的问题 但是却存在一个巨大隐患,对于这种const priceList = [1, 2] 。map.get会被认定为是同一个 直接return出去 返回了相同的引用地址 导致深拷贝失效
如何解决这个问题
const deepCopy = (data) => { if (typeof data !== 'object') { return data } const copy = new data.constructor() for (let key in data) { if (data.hasOwnProperty(key)) { copy[key] = deepCopy(data[key]) } } return copy }
直接进行深度递归赋值拷贝即可-这样即可解决重复引用的问题
个人理解:
我认为应该不是从priceList数组开始出现的引用问题,而是从animals这里出的问题。series[animals,animals]。animals是相同的,所以出现了这个问题。
标签:map,copy,cloneDeep,key,const,拷贝,ladsh,data,priceList From: https://www.cnblogs.com/zhaoleiFree/p/17770846.html