首页 > 其他分享 >关于ladsh深拷贝的问题:cloneDeep()

关于ladsh深拷贝的问题:cloneDeep()

时间:2023-10-17 22:22:40浏览次数:33  
标签:map copy cloneDeep key const 拷贝 ladsh data priceList

内容来源: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

相关文章

  • 手写深拷贝
    深拷贝基本实现1深拷贝基本实现2functionisObject(value){3constvalueType=typeofvalue4return(value!==null)&&(valueType==='object'||valueType==='function')5}6functiondeepClone(originValue){7//判断传入的originValu......
  • 手写节流、深拷贝函数实现
    防抖函数基本实现1functiondebounce(fn,delay){2lettimer=null3returnfunction(...args){4if(timer)clearTimeout(timer)5timer=setTimeout(()=>{6fn.apply(this,args)7},delay);8}9}防抖函数完正版......
  • BeanUtils.copyProperties这个方法是深拷贝浅拷贝,还是深复制浅复制?
    1、关于BeanUtils.copyProperties方法的拷贝类型,它是浅拷贝哦。这意味着在拷贝对象时,它只会复制对象的引用而不会复制对象的内容。所以,如果原始对象中的某个属性发生改变,拷贝后的对象中的相应属性也会随之改变。当然,如果你希望进行深拷贝或深复制,需要使用其他方法来实现哦`BeanUt......
  • Python - 深拷贝一个带有指向自身引用的列表,会报错么?紧接着用==比较,会报错么?
    问题描述深拷贝一个带有指向自身引用的列表:列表x中有指向自身的引用,因此x是一个无限嵌套的列表。importcopyx=[1]x.append(x)>>x[1,[...]]y=copy.deepcopy(x)>>y[1,[...]] 深拷贝不报错但是我们发现深度拷贝x到y后,程序并没有出现stackoverf......
  • 浅谈深拷贝和浅拷贝
    深拷贝和浅拷贝深拷贝importcopylist1=[1,2,3,4,[5,6,7]]list2=copy.deepcopy(list1)print(list1)print(list2)[1,2,3,4,[5,6,7]][1,2,3,4,[5,6,7]]list1[0]+=1print(list1)print(list2)[2,2,3,4,[5,6,7]][1,2,3,4,[5,6,7]]list1[4]......
  • 关于C++拷贝控制
    通常来说,对于类内动态分配资源的类需要进行拷贝控制:要在拷贝构造函数、拷贝赋值运算符、析构函数中实现安全高效的操作来管理内存。但是资源管理并不是一个类需要定义自己的拷贝控制成员的唯一原因。C++Primer第5版中给出了一个Message类与Folder类的例子,分别表示电子邮件消息......
  • java本地文件多线程拷贝
    简单介绍:本地文件多线程拷贝是指通过多个线程同时进行文件复制操作。传统的文件复制操作往往是串行进行的,当需要复制单个大文件时,复制速度往往会比较慢。而采用多线程进行文件拷贝可以提高效率。通过同时创建多个线程,每个线程负责复制不同的文件或者不同的文件片段,可以充分利用计......
  • python拷贝文件
    在Python中拷贝文件可以使用shutil模块importshutil#源文件路径src_file='/path/to/source/file.txt'#目标文件路径dst_file='/path/to/destination/file.txt'#使用shutil模块的copy2函数进行拷贝shutil.copy2(src_file,dst_file) 在这个示例中,shutil.cop......
  • python 拷贝整个目录及其子目录和文件
    拷贝整个目录及其子目录和文件,可以使用shutil.copytree()函数。 importshutil#源目录路径src_dir='/path/to/source/directory'#目标目录路径dst_dir='/path/to/destination/directory'#使用shutil模块的copytree函数进行拷贝shutil.copytree(src_dir,dst_d......
  • 零拷贝并非万能解决方案:重新定义数据传输的效率极限
    PageCache有什么作用?在我们前面讲解零拷贝的内容时,我们了解到一个重要的概念,即内核缓冲区。那么,你可能会好奇内核缓冲区到底是什么?这个专有名词就是PageCache,也被称为磁盘高速缓存。也可以看下windows下的缓存区:如图所示:零拷贝进一步提升性能的原因在于PageCache技术的使用。......