• JS--对象数组深拷贝的方法


    原文网址:JS--对象数组深拷贝的方法_IT利刃出鞘的博客-CSDN博客

    简介

            本文用示例介绍JavaScript对象数组深拷贝的方法。

    问题描述

            对于普通数组(数组元素为数字或者字符串),深拷贝很简单,拷贝之后两个数组指针指向的存储地址不同,从而完成深拷贝。

    1. ar test = [1,2,3];//原数组
    2. var testCopy = [].concat(test);//拷贝数组
    3. testCopy[0]=4;
    4. console.log(test);// [1,2,3]
    5. console.log(testCopy);//[4,2,3]

    对于对象数组

    1. //形如
    2. var objArr=[{"name":''weifeng"},{"name":"boy"}]

            如果还是利用上述的[].concat()方法拷贝数组,则获取的结果仍然是浅拷贝,改变一个数组的内容,另一个数组的内容会改变。例子:

    1. var test = [{"name":"demi"},{"name":"lily"}];//原数组
    2. var testCopy = [].concat(test);//拷贝数组
    3. testCopy[1].name="test";
    4. console.log(test);// [{"name":"demi"},{"name":"test"}]
    5. console.log(testCopy);//[{"name":"demi"},{"name":"test"}]

            从例子上可以看出,这种对于对象数组的拷贝,由于数组内部属性值为引用对象,因此整个拷贝还是浅拷贝,拷贝之后数组各个值的指针还是指向相同的存储地址。

    解决方案

    方案1:JSON转换(不推荐)

    1. ar test = [{"name":"demi"},{"name":"lily"}];//原数组
    2. var testCopy = [].concat(JSON.parse(JSON.stringify(test)));//转换成json再转换成对象实现深拷贝
    3. testCopy[1].name="test";
    4. console.log(test);// [{"name":"demi"},{"name":"lily"}]
    5. console.log(testCopy);//[{"name":"demi"},{"name":"test"}]

            仅在原对象包含可序列化值类型且没有任何循环引用时才有效。不可序列化值类型的一个例子:Date 对象 - Date 对象在JSON.stringify时会被转化为 String,JSON.parse 只能将其解析为字符串而无法解析回其原始的 Date 对象。

    可序列化的值类型(没问题的类型)有:Boolean,Number,String,对象,数组

    不可序列化的值类型(有问题的类型)有(以下问题都发生在JSON.stringify时):

    1. undefined,Function,Symbol 时,它被忽略掉
    2. Infinity,NaN 会被变成 null
    3. Date 对象会被转化为 String (默认调用date.toISOString())

    方案2:lodash的cloneDeep(推荐)

    1. const _ = require('lodash');
    2. let one_brand = [
    3. {name: 'A', count: 1, value: Infinity},
    4. {name: 'B', count: 2},
    5. ]
    6. // 深拷贝
    7. let two_brand = _.cloneDeep(one_brand);
    8. console.log("改变前:")
    9. console.log(one_brand)
    10. console.log(two_brand)
    11. two_brand[1].count = 0;
    12. console.log("改变后:")
    13. console.log(one_brand)
    14. console.log(two_brand)

    结果

    1. 改变前:
    2. [ { name: 'A', count: 1, value: Infinity },
    3. { name: 'B', count: 2 } ]
    4. [ { name: 'A', count: 1, value: Infinity },
    5. { name: 'B', count: 2 } ]
    6. 改变后:
    7. [ { name: 'A', count: 1, value: Infinity },
    8. { name: 'B', count: 2 } ]
    9. [ { name: 'A', count: 1, value: Infinity },
    10. { name: 'B', count: 0 } ]

  • 相关阅读:
    java实战:Redis实现查找附近的人
    Java基础——运算符表达式
    【趣学算法】Day2 贪心算法——最优装载问题
    70、window11+visual studio2019+共享内存进行数据传输
    Tomcat隔离web原理和热加载热部署
    Codeforces Round 900 (Div. 3)(A-F)
    批量修改视频尺寸:简单易用的视频剪辑软件教程
    前端Vue-vue-element-admin-router.addRoutes
    Rust中的智能指针:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak<T>
    Python之正则表达式
  • 原文地址:https://blog.csdn.net/feiying0canglang/article/details/126943860