一、背景

某个项目里,存在一个对象数组,我用 lodashfilter() 函数,分别生成了 A、B 两个新的对象数组,但我遍历了 B 数组,改造里面的每一个对象,没想到引起 A 数组的里对象发生了变化,引发了错误。

这是一个基础的,对引用类型——对象没有使用深拷贝的问题,我疏忽了,特此记录下。

二、例子

1、浅拷贝

const _ = require('lodash');let one_brand = [{name: 'A', count: 1, value: Infinity},{name: 'B', count: 2},
]// 浅拷贝
// 方法一
let two_brand = one_brand.slice(0);
// 方法二(推荐)
let two_brand = _.clone(one_brand) console.log("改变前:")
console.log(one_brand)
console.log(two_brand) two_brand[1].count = 0;console.log("改变后:")
console.log(one_brand)
console.log(two_brand)

return:

改变前:
[ { name: 'A', count: 1, value: Infinity },{ name: 'B', count: 2 } ]
[ { name: 'A', count: 1, value: Infinity },{ name: 'B', count: 2 } ]
改变后:
[ { name: 'A', count: 1, value: Infinity },{ name: 'B', count: 0 } ]
[ { name: 'A', count: 1, value: Infinity },{ name: 'B', count: 0 } ]

你会发现改变了 two_brand 的一个对象,one_brand 的那个对应的对象也改变了。这样不行。

2、深拷贝

const _ = require('lodash');let one_brand = [{name: 'A', count: 1, value: Infinity},{name: 'B', count: 2},
]// 深拷贝
// 方法一
let two_brand = one_brand.map(o => Object.assign({}, o));
// 方法二
let two_brand = one_brand.map(o => ({...o}));
// 方法三(推荐)
let two_brand = _.cloneDeep(one_brand);console.log("改变前:")
console.log(one_brand)
console.log(two_brand) two_brand[1].count = 0;console.log("改变后:")
console.log(one_brand)
console.log(two_brand)

return:

改变前:
[ { name: 'A', count: 1, value: Infinity },{ name: 'B', count: 2 } ]
[ { name: 'A', count: 1, value: Infinity },{ name: 'B', count: 2 } ]
改变后:
[ { name: 'A', count: 1, value: Infinity },{ name: 'B', count: 2 } ]
[ { name: 'A', count: 1, value: Infinity },{ name: 'B', count: 0 } ]

3、拓展

其实网上还有一种方法:

let two_brand = JSON.parse(JSON.stringify(one_brand))

这种方法存在很大的问题。虽然他在 stackoverflow 是得票最多的一个答案。(https://stackoverflow.com/questions/597588/how-do-you-clone-an-array-of-objects-in-javascript)

它的主要缺点是,只限于处理可被 JSON.stringify() 编码的值。

JSON.stringify() 将编码 JSON 支持的值。包含 Boolean,Number,String,以及对象,数组。其他任何内容都将被特殊处理。

undefinedFunctionSymbol 时,它被忽略掉
InfinityNaN 会被变成 null
Date 对象会被转化为 String (默认调用date.toISOString())

问:为什么JSON.stringify() 编码 JSON 支持的值那么少呢?

因为JSON是一个通用的文本格式,和语言无关。设想如果将函数定义也stringify的话,如何判断是哪种语言,并且通过合适的方式将其呈现出来将会变得特别复杂。特别是和语言相关的一些特性,比如JavaScript中的Symbol。

转载于:https://www.cnblogs.com/xjnotxj/p/9810534.html

如何深拷贝一个对象数组?相关推荐

  1. java怎样定义一个对象数组,java定义一个对象数组

    java怎么定义一个动态数组,Java初学者入门应该掌握的30个概念,java定义一个对象数组,java一维数组定义 摘要: java 是面向对象程序设计语言, 对象数组作为 javase 中的基础. ...

  2. 向一个对象数组里面添加新的属性 + 将一个对象数组数据拿出来变成另一个对象

    向一个对象数组里面添加新的属性 var arry= [{a:11,b:22,c:33,d:44},{a:11,b:0,c:0,d:44},{a:11,b:22,c:99,d:99}]; var arr ...

  3. JavaScript中一个对象数组按照另一个数组排序

    JavaScript中一个对象数组按照另一个数组排序 需求:排序 const arr1 = [33, 11, 55, 22, 66]; const arr2 = [{age: 55}, {age: 2 ...

  4. 习题 9.5 建立一个对象数组,内放5个学生的数据(学号、成绩),设立一个函数max,用指向对象的指针作函数参数,在max函数中找出5个学生中成绩最高者,并输出其学号。

    C++程序设计(第三版) 谭浩强 习题9.5 个人设计 习题 9.5 建立一个对象数组,内放5个学生的数据(学号.成绩),设立一个函数max,用指向对象的指针作函数参数,在max函数中找出5个学生中成 ...

  5. 习题:设计一个学生类,其中数据成员有学号、姓名、年龄、3门课程的成绩,以及若干成员函数。并利用这个类建立一个对象数组。

    完整题干: 设计一个学生类,其中数据成员有学号.姓名.年龄.3门课程的成绩,以及若干成员函数.并利用这个类建立一个对象数组.(1)求第一门课的平均成绩:(2)找出有两门以上课程不及格的学生,输出他们的 ...

  6. 刚学会深拷贝一个对象,学妹却问我怎么深拷贝一个图

    前言 在前面,我写过一篇Java的深浅拷贝,那是基于对象的拷贝,但放眼数据结构与算法中,你有考虑过怎么拷贝一个图吗?(无向图) 在此之前,你需要对一些概念搞清楚:什么是深拷贝.浅拷贝? 浅拷贝:如果拷 ...

  7. 深拷贝一个对象会了,怎么深拷贝一个图?

    原创公众号:bigsai 如有帮助欢迎一键三联 文章已收录在 全网都在关注的数据结构与算法学习仓库 欢迎star 前言 在前面,我写过一篇Java的深浅拷贝,那是基于对象的拷贝,但放眼数据结构与算法中 ...

  8. python深拷贝一个对象_Python中的深拷贝和浅拷贝以及存在的问题

    在讨论浅拷贝和深拷贝之前,首先要了解python中两个对象比较==和is==操作符进行的是对象的值判断,比较两个对象的值是否相等. is操作符进行的是对象的身份标识的判断,比较两个对象的内存地址是否相 ...

  9. python深拷贝一个对象_Python对象的深拷贝和浅拷贝详解

    本文内容是在<Python核心编程2>上看到的,感觉很有用便写出来,给大家参考参考! 浅拷贝 首先我们使用两种方式来拷贝对象,一种是切片,另外一种是工厂方法.然后使用id函数来看看它们的标 ...

最新文章

  1. Java查询spark中生成的文件_java+spark-sql查询excel
  2. jittor和pytorch生成网络对比之stargan
  3. Android draw9patch点九图常识
  4. sidekiq安装及使用
  5. 从VS2008+QT4到VS2015+QT5迁移过程中遇到的问题及解决方法
  6. 梳理十年Kaggle竞赛,看自然语言处理的变迁史
  7. html文件里的scr是什么,HTML中关于url、scr、href的区别
  8. c语言图像浏览器,单片机采用浏览器进行监控将给软件的编程带来极大的便利...
  9. python教学案例-Python机器学习经典实例
  10. rocketmq 初探(二)
  11. 48_并发编程-线程-资源共享/锁
  12. tcp和udp通讯协议
  13. 中国移动公布5G核心网大单 全面加快5G网络部署
  14. oracle Interval 分区维护与管理要点
  15. linux客户端掉线重连,SSH自动断开后重连的解决方案
  16. 灰、黄、蓝三种颜色的收集装置模型练习及实现思路
  17. python寻峰,[LeetCode][Python]162. 寻找峰值
  18. 高斯消元简单线性代数线性基学习记录
  19. XTU 1278 Arithmetic Sequence
  20. 光伏MPPT电路效率对比实测

热门文章

  1. 计算机设备安全检查表,信息安全检查表
  2. Bit-Z图解“推荐返佣”那些事儿
  3. android surfaceflinger研究----显示系统
  4. 【问链-区块链基础知识系列】 第十五课 数字货币交易所的前世、今生和未来(二)
  5. struts启动过滤器异常_面试必备:网关异常了怎么办?如何做全局异常处理?
  6. JZOJ 5050. 【GDOI2017模拟一试4.11】颜色树
  7. oracle100个常见问题,Oracle初学者必知的100个问题(三)
  8. python importlib_metadata_Python 动态导入对象,importlib.import_module()的使用方法
  9. Data Mining的十种分析方法
  10. BZOJ 4823 Luogu P3756 [CQOI2017]老C的方块 (网络流、最小割)