js拷贝数组对象:浅拷贝&深拷贝

2023-05-16

前言

js拷贝数组对象:浅拷贝&深拷贝,包括:Object.assign、concat、slice、JSON.parse(JSON.stringify())
场景:弹窗选择组织结构(树形结构),选择后显示相关数据至输入框中(每次选择都将重新拷贝初始组织结构数据)
博客地址:芒果橙的个人博客 【http://mangocheng.com】

文章目录

    • 前言
    • 关于浅拷贝、深拷贝的使用场景
    • 常用的拷贝方法
      • 场景
      • 1. 普通赋值语法-简单数据、复杂数据均为浅拷贝
      • 2. Object.assign(target,source)-简单数据深拷贝、复杂数据浅拷贝
      • 3. concat()/slice()-简单数据深拷贝、复杂数据浅拷贝
      • 4. JSON.parse(JSON.stringify())-简单数据、复杂数据均为深拷贝
      • 参考代码


关于浅拷贝、深拷贝的使用场景

在开发过程中,需要基于某一个对象上进行新增修改的场景是非常多的,因此经常会进行对象的拷贝。在不需要多次复用源数据的情况下,那么对象的拷贝只需要进行赋值就能满足要求,即浅拷贝,但有时候需要多次使用到初始的原数组,那么则需要深拷贝,以达到每次拷贝原数组都是初始数据的目的

常用的拷贝方法

场景

  • 弹窗选择组织结构(树形结构),选择后显示相关数据至输入框中

  • 数据格式:[ {},{}]

  • 场景数据,案例使用

const copy = {
    // 源数组1:简单数组
	sourceArr: ['a', 'b', 'c'],			
    targetArr: [],
    // 源数组2:复杂数组
    sourceArrAndObj: [					
        {
            'A': 1,
            'B': 2
        },
        {
            'S': 10,
            'T': 20
        }
    ],
    targetArrAndObj: []
}

1. 普通赋值语法-简单数据、复杂数据均为浅拷贝

目标数组=源数组

  • 测试数据
    • 源数组1-sourceArr:[‘a’, ‘b’, ‘c’]
    • 目标数组1-targetArr:[]
    • 源数组2-sourceArrAndObj:[ { ‘A’ : 1, ‘B’:2 }, { ‘S’ : 10, ‘T’ : 20 } ]
    • 目标数组2-targetArrAndObj: []
  • 操作
    • 赋值目标数组
    • 增加目标数组1数据[d、e]
    • 增加目标数组2数据属性[C、D]、修改属性[S、T]
  • 输出
    • 源数组1-sourceArr = a,b,c,d,e
    • 源数组2-sourceArrAndObj = [ { ‘A’ : 1, ‘B’:2, ‘C’ : 3, ‘D’ : 4 }, { ‘S’ : 30, ‘T’ : 40 } ]
  • 结果&结论
    • 源数组改变
    • 浅拷贝作用
console.log('sourceArr = ', this.sourceArr.join());
        console.log('sourceArrAndObj=', this.sourceArrAndObj);
        this.targetArr = this.sourceArr;
        this.targetArrAndObj = this.sourceArrAndObj;
        console.log('赋值后:targetArr = ', this.targetArr.join());
        console.log('赋值后:targetArrAndObj=', this.targetArrAndObj);

        console.log('=====增加目标数组数据[d、e]');
        this.targetArr.push('d');
        this.targetArr.push('e');

        console.log('=====增加目标数组数据属性[C、D];修改属性[S、T]');
        this.targetArrAndObj[0].C = 3;
        this.targetArrAndObj[0].D = 4;
        this.targetArrAndObj[1].S = 30;
        this.targetArrAndObj[1].T = 40;

        console.log('更新后:sourceArr = ', this.sourceArr.join());
        console.log('更新后:sourceArrAndObj=', this.sourceArrAndObj);

2. Object.assign(target,source)-简单数据深拷贝、复杂数据浅拷贝

Object.assign(目标数组,源数组)

  • 测试简单数据
    • 源数组sourceArr:[‘a’, ‘b’, ‘c’]
    • 目标数组targetArr:[]
  • 操作
    • 增加目标数组数据[d、e]
  • 输出
    • targetArr = a,b,c,d,e
    • sourceArr= a,b,c
  • 结果&结论
    • 源数组未改变
    • 深拷贝作用
console.log('=========简单数组对象=========');
        console.log('sourceArr = ', this.sourceArr.join());
        Object.assign(this.targetArr, this.sourceArr);
        console.log('拷贝后:targetArr = ', this.targetArr.join());
        console.log('=====增加目标数组数据[d、e]');
        this.targetArr.push('d');
        this.targetArr.push('e');

        console.log('更新后:sourceArr = ', this.sourceArr.join());
        console.log('更新后:targetArr = ', this.targetArr.join());
  • 测试复杂数据
    • 源数组sourceArrAndObj:[ { ‘A’ : 1, ‘B’:2 }, { ‘S’ : 10, ‘T’ : 20 } ]
    • 目标数组targetArrAndObj: []
  • 操作
    • 增加目标数组数据属性[C、D]
    • 修改属性[S、T]
  • 输出
    • sourceArrAndObj:[ { ‘A’ : 1, ‘B’:2, ‘C’ : 3, ‘D’ : 4 }, { ‘S’ : 30, ‘T’ : 40 } ]
    • targetArrAndObj:[ { ‘A’ : 1, ‘B’:2, ‘C’ : 3, ‘D’ : 4 }, { ‘S’ : 30, ‘T’ : 40 } ]
  • 结果&结论
    • 源数组改变,与目标数组一样
    • 浅拷贝作用
console.log('=========复杂数组对象=========')
        console.log('sourceArrAndObj=', this.sourceArrAndObj);
        Object.assign(this.targetArrAndObj, this.sourceArrAndObj);
        console.log('拷贝后:targetArrAndObj=', this.targetArrAndObj);
        console.log('=====增加目标数组数据属性[C、D];修改属性[S、T]');

        this.targetArrAndObj[0].C = 3;
        this.targetArrAndObj[0].D = 4;
        this.targetArrAndObj[1].S = 30;
        this.targetArrAndObj[1].T = 40;

        console.log('更新后:sourceArrAndObj=', this.sourceArrAndObj);
        console.log('更新后:targetArrAndObj=', this.targetArrAndObj);

3. concat()/slice()-简单数据深拷贝、复杂数据浅拷贝

目标数组=源数组.concat();

目标数组=源数组.slice();

  • 测试简单数据
    • 源数组sourceArr:[‘a’, ‘b’, ‘c’]
    • 目标数组targetArr:[]
  • 操作
    • 增加目标数组数据[d、e]
  • 输出
    • sourceArr= a,b,c
    • targetArr = a,b,c,d,e
  • 结果&结论
    • 源数组未改变
    • 深拷贝作用
console.log('=========简单数组对象=========');
        console.log('sourceArr = ', this.sourceArr.join());
        this.targetArr = this.sourceArr.concat();
        // this.targetArr = this.sourceArr.slice();

        console.log('拷贝后:targetArr = ', this.targetArr.join());
        console.log('=====增加目标数组数据[d、e]');
        this.targetArr.push('d');
        this.targetArr.push('e');

        console.log('更新后:sourceArr = ', this.sourceArr.join());
        console.log('更新后:targetArr = ', this.targetArr.join());
  • 测试复杂数据
    • 源数组sourceArrAndObj:[ { ‘A’ : 1, ‘B’:2 }, { ‘S’ : 10, ‘T’ : 20 } ]
    • 目标数组targetArrAndObj: []
  • 操作
    • 增加目标数组数据属性[C、D]
    • 修改属性[S、T]
  • 输出
    • sourceArrAndObj:[ { ‘A’ : 1, ‘B’:2, ‘C’ : 3, ‘D’ : 4 }, { ‘S’ : 30, ‘T’ : 40 } ]
    • targetArrAndObj:[ { ‘A’ : 1, ‘B’:2, ‘C’ : 3, ‘D’ : 4 }, { ‘S’ : 30, ‘T’ : 40 } ]
  • 结果&结论
    • 源数组改变,与目标数组一样
    • 浅拷贝作用
console.log('=========复杂数组对象=========')
        console.log('sourceArrAndObj=', this.sourceArrAndObj);
        this.targetArrAndObj = this.sourceArrAndObj.concat();
        // this.targetArrAndObj = this.sourceArrAndObj.slice();

        console.log('拷贝后:targetArrAndObj=', this.targetArrAndObj);
        console.log('=====增加目标数组数据属性[C、D];修改属性[S、T]');

        this.targetArrAndObj[0].C = 3;
        this.targetArrAndObj[0].D = 4;
        this.targetArrAndObj[1].S = 30;
        this.targetArrAndObj[1].T = 40;

        console.log('更新后:sourceArrAndObj=', this.sourceArrAndObj);
        console.log('更新后:targetArrAndObj=', this.targetArrAndObj);

4. JSON.parse(JSON.stringify())-简单数据、复杂数据均为深拷贝

目标数组=JSON.parse(JSON.stringify(源数组))

  • 测试简单数据
    • 源数组sourceArr:[‘a’, ‘b’, ‘c’]
    • 目标数组targetArr:[]
  • 操作
    • 增加目标数组数据[d、e]
  • 输出
    • targetArr = a,b,c,d,e
    • sourceArr= a,b,c
  • 结果&结论
    • 源数组未改变
    • 深拷贝作用
console.log('=========简单数组对象=========');
        console.log('sourceArr = ', this.sourceArr.join());
        this.targetArr = JSON.parse(JSON.stringify(this.sourceArr));

        console.log('拷贝后:targetArr = ', this.targetArr.join());
        console.log('=====增加目标数组数据[d、e]');
        this.targetArr.push('d');
        this.targetArr.push('e');

        console.log('更新后:sourceArr = ', this.sourceArr.join());
        console.log('更新后:targetArr = ', this.targetArr.join());
  • 测试复杂数据
    • 源数组sourceArrAndObj:[ { ‘A’ : 1, ‘B’:2 }, { ‘S’ : 10, ‘T’ : 20 } ]
    • 目标数组targetArrAndObj: []
  • 操作
    • 增加目标数组数据属性[C、D]
    • 修改属性[S、T]
  • 输出
    • sourceArrAndObj:[ { ‘A’ : 1, ‘B’:2 }, { ‘S’ : 10, ‘T’ : 20 } ]
    • targetArrAndObj:[ { ‘A’ : 1, ‘B’:2, ‘C’ : 3, ‘D’ : 4 }, { ‘S’ : 30, ‘T’ : 40 } ]
  • 结果&结论
    • 源数组未改变
    • 深拷贝作用
console.log('=========复杂数组对象=========')
        console.log('sourceArrAndObj=', this.sourceArrAndObj);
        this.targetArrAndObj = JSON.parse(JSON.stringify(this.sourceArrAndObj));

        console.log('拷贝后:targetArrAndObj=', this.targetArrAndObj);
        console.log('=====增加目标数组数据属性[C、D];修改属性[S、T]');

        this.targetArrAndObj[0].C = 3;
        this.targetArrAndObj[0].D = 4;
        this.targetArrAndObj[1].S = 30;
        this.targetArrAndObj[1].T = 40;

        console.log('更新后:sourceArrAndObj=', this.sourceArrAndObj);
        console.log('更新后:targetArrAndObj=', this.targetArrAndObj);

参考代码

const copy = {

    sourceArr: ['a', 'b', 'c'],
    targetArr: [],
    sourceArrAndObj: [
        {
            'A': 1,
            'B': 2
        },
        {
            'S': 10,
            'T': 20
        }
    ],
    targetArrAndObj: [],

    /**
     * = 赋值
     */
    equalSign: function () {

        console.log('sourceArr = ', this.sourceArr.join());
        console.log('sourceArrAndObj=', this.sourceArrAndObj);
        this.targetArr = this.sourceArr;
        this.targetArrAndObj = this.sourceArrAndObj;
        console.log('赋值后:targetArr = ', this.targetArr.join());
        console.log('赋值后:targetArrAndObj=', this.targetArrAndObj);

        console.log('=====增加目标数组数据[d、e]');
        this.targetArr.push('d');
        this.targetArr.push('e');

        console.log('=====增加目标数组数据属性[C、D];修改属性[S、T]');
        this.targetArrAndObj[0].C = 3;
        this.targetArrAndObj[0].D = 4;
        this.targetArrAndObj[1].S = 30;
        this.targetArrAndObj[1].T = 40;

        console.log('更新后:sourceArr = ', this.sourceArr.join());
        console.log('更新后:sourceArrAndObj=', this.sourceArrAndObj);
    },

    /**
     * Object.assign()
     */
    objectAssign: function () {
        console.log('=========简单数组对象=========');
        console.log('sourceArr = ', this.sourceArr.join());
        Object.assign(this.targetArr, this.sourceArr);
        console.log('拷贝后:targetArr = ', this.targetArr.join());
        console.log('=====增加目标数组数据[d、e]');
        this.targetArr.push('d');
        this.targetArr.push('e');

        console.log('更新后:sourceArr = ', this.sourceArr.join());
        console.log('更新后:targetArr = ', this.targetArr.join());


        console.log('=========复杂数组对象=========')
        console.log('sourceArrAndObj=', this.sourceArrAndObj);
        Object.assign(this.targetArrAndObj, this.sourceArrAndObj);
        console.log('拷贝后:targetArrAndObj=', this.targetArrAndObj);
        console.log('=====增加目标数组数据属性[C、D];修改属性[S、T]');

        this.targetArrAndObj[0].C = 3;
        this.targetArrAndObj[0].D = 4;
        this.targetArrAndObj[1].S = 30;
        this.targetArrAndObj[1].T = 40;

        console.log('更新后:sourceArrAndObj=', this.sourceArrAndObj);
        console.log('更新后:targetArrAndObj=', this.targetArrAndObj);
    },

    /**
     * concat方法
     */
    concataAndSlice: function () {
        console.log('=========简单数组对象=========');
        console.log('sourceArr = ', this.sourceArr.join());
        this.targetArr = this.sourceArr.concat();
        // this.targetArr = this.sourceArr.slice();

        console.log('拷贝后:targetArr = ', this.targetArr.join());
        console.log('=====增加目标数组数据[d、e]');
        this.targetArr.push('d');
        this.targetArr.push('e');

        console.log('更新后:sourceArr = ', this.sourceArr.join());
        console.log('更新后:targetArr = ', this.targetArr.join());

        console.log('=========复杂数组对象=========')
        console.log('sourceArrAndObj=', this.sourceArrAndObj);
        this.targetArrAndObj = this.sourceArrAndObj.concat();
        // this.targetArrAndObj = this.sourceArrAndObj.slice();

        console.log('拷贝后:targetArrAndObj=', this.targetArrAndObj);
        console.log('=====增加目标数组数据属性[C、D];修改属性[S、T]');

        this.targetArrAndObj[0].C = 3;
        this.targetArrAndObj[0].D = 4;
        this.targetArrAndObj[1].S = 30;
        this.targetArrAndObj[1].T = 40;

        console.log('更新后:sourceArrAndObj=', this.sourceArrAndObj);
        console.log('更新后:targetArrAndObj=', this.targetArrAndObj);
    },

    /**
     * json转换
     */
    json2array: function () {
        console.log('=========简单数组对象=========');
        console.log('sourceArr = ', this.sourceArr.join());
        this.targetArr = JSON.parse(JSON.stringify(this.sourceArr));

        console.log('拷贝后:targetArr = ', this.targetArr.join());
        console.log('=====增加目标数组数据[d、e]');
        this.targetArr.push('d');
        this.targetArr.push('e');

        console.log('更新后:sourceArr = ', this.sourceArr.join());
        console.log('更新后:targetArr = ', this.targetArr.join());

        console.log('=========复杂数组对象=========')
        console.log('sourceArrAndObj=', this.sourceArrAndObj);
        this.targetArrAndObj = JSON.parse(JSON.stringify(this.sourceArrAndObj));

        console.log('拷贝后:targetArrAndObj=', this.targetArrAndObj);
        console.log('=====增加目标数组数据属性[C、D];修改属性[S、T]');

        this.targetArrAndObj[0].C = 3;
        this.targetArrAndObj[0].D = 4;
        this.targetArrAndObj[1].S = 30;
        this.targetArrAndObj[1].T = 40;

        console.log('更新后:sourceArrAndObj=', this.sourceArrAndObj);
        console.log('更新后:targetArrAndObj=', this.targetArrAndObj);

    },


    test: function () {
        this.equalSign();
        // this.objectAssign();
        // this.concataAndSlice();
        // this.json2array();
    }


}

copy.test();

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

js拷贝数组对象:浅拷贝&深拷贝 的相关文章

  • ROS话题发布和订阅节点的C++&Python实现

    本文将分别使用C 43 43 和Python来实现话题发布者和订阅者 xff0c 首先创建一个功能包 xff0c 命名为topic pub sub xff0c 添加roscpp xff0c rospy等依赖项 C 43 43 实现 创建话题
  • matlab 数值计算课 二阶微分方程-龙格库塔方法 & ODE45

    详见mathworks 龙格库塔方法 写成矩阵 xff08 状态方程 xff09 的形式更简洁一点 xff08 其实这两种方法结果是一样的 xff0c 如果C是 1 0 0 的话 xff0c 就很明显了 xff09 例如 xff1a 求系统
  • 【信息奥赛题解】昆虫繁殖(详细分析题解 & C++ 代码)

    昆虫繁殖问题 x1f31f 题目名称 昆虫繁殖 题目描述 科学家在热带森林中发现了一种特殊的昆虫 xff0c 这种昆虫的繁殖能力很强 每对成虫过 X X X 个月后开始产卵 xff0c 每月产 Y Y
  • ESP实验02-读取DS1307&eerom34c32

    1 模块介绍 本实验主要用到两个模块 esp32 tinyRTC 模块的图片如下所示 xff1a esp32模块型号为ESP32Devkitc v4 xff0c 是启明云端官方的开发板 与乐鑫官方的完全一致 xff0c 引脚顺序 xff0c
  • 计算机图形学方向和前景&&3D

    我是刚入坑计算机图形学的小菜鸟 xff0c 在百度上搜索计算机图形学方向和前景和3D xff0c 几乎不能搜到什么有用的东西 xff0c google还能搜到些有用的 xff0c 但是需要翻墙 恰好前几天山大承办的games xff0c 北
  • [Machine Learning & Algorithm] 随机森林(Random Forest)

    1 什么是随机森林 xff1f 作为新兴起的 高度灵活的一种机器学习算法 xff0c 随机森林 xff08 Random Forest xff0c 简称RF xff09 拥有广泛的应用前景 xff0c 从市场营销到医疗保健保险 xff0c
  • Kibana学习&理解

    注 xff1a 本篇的kibana基于7 5 1版本 Kibana是什么 xff1f kibana是一个数据可视化平台 展示与分析 将es里面的东西通过各种图表展示出来 xff0c 还可以执行es的各种搜索 amp 监控 Kibana环境搭
  • Liunx下源代码安装&&make&&makefile

    Linux下安装软件的方式分为源代码安装和二进制安装 源代码安装 xff0c 即使用应用程序源代码进行编译安装二进制安装 xff0c 例如red hat发行的 rpm包 debian发行的 deb包 源代码安装 用c语言为例 include
  • CMake&CMakeList.txt

    1 各种关系 在各种开源项目中 xff0c 经常会发现项目中除了代码源文件 xff0c 还包含了 CMakeList txt Makefile 文件 xff0c 在项目的编译时候需要用到的命令有 cmake make 我们本次想搞清楚他们之
  • 【浅墨著作】《逐梦旅程:Windows游戏编程之从零开始》勘误&配套源代码下载...

    I 39 m back 恩 xff0c 几个月不见 xff0c 大家还好吗 xff1f 这段时间真的好多童鞋在博客里留言说或者发邮件说浅墨你回来继续更新博客吧 woxiangnifrr童鞋说每天都在来浅墨的博客逛一下看有没有更新 xff0c
  • Intel RealSense L515&Unreal Engine 4调试记录

    文章目录 前言一 安装与配置1 安装前置条件2 配置 二 编译与运行1 编译2 运行 填坑与测试1 填坑2 测试 前言 Intel RealSense系列推出了适用于Unreal Engine 4的相关插件 xff0c 官网提供了相关示例代
  • 对‘cv Mat Mat()’未定义的引用‘cv imread(cv String const&, int)’未定义的引用 ...的解决办法

    对 cv Mat Mat 未定义的引用 cv imread cv String const amp int 未定义的引用 的解决办法 视觉SLAM十四讲的ch5的部分代码 xff0c 运行时出现了大面积的报错 xff0c 说相应的函数没有定
  • Jetson xavier Nx & jetson nano 上手 + 刷机

    本教程基于Jetson xavier Nx开发套件 本教程参考Nvidia官方刷机教程 制作启动盘 在官方下载中心下载SD卡镜像并解压 下载SD Memory Card Formatter 需要划到页面最下方 xff0c 点击 Accept
  • Chrome安装Proxy SwitchyOmega插件&Ubuntu20.04安装Proxychains

    目录 1 Chrome浏览器1 1 安装Proxy SwitchyOmega插件1 2 安装Proxy SwitchyOmega插件 2 Ubuntu服务器2 1 安装2 2 配置2 3 测试2 4 异常处理 1 Chrome浏览器 1 1
  • STM32调试方式JTAG&SWD的区别

    在学习STM32时 xff0c 我们经常会遇到JTAG和SWD的调试方法 xff0c 还涉及到Jlink Ulink Stlink等 xff0c JTAG和SWD是ARM板一种调试模式 后面三种都是实现这种模式的一种工具 xff0c 他们之
  • ROS通信机制~话题通信(Publisher&Subscriber)·笔记2

    系列文章目录 xff1a ROS开发 xff08 ubuntu xff09 笔记 1 嘻 嘻的博客 CSDN博客 ROS通信机制 服务通信 server amp client 笔记3 嘻 嘻的博客 CSDN博客 话题通信 理论模型 xff1
  • ROS速成之发送&接收消息

    人真的老了 xff0c 扔了个周末 xff0c 完全不记得干了什么 论纪录的重要性啊 xff0c 当时觉得明白的很 xff0c 你扔两天试试 xff1f 扔一年试试 xff1f 扔几年试试 xff1f 最近参加的各种项目脑疼眼乏 xff0c
  • Docker数据卷&&自定义Docker镜像

    目录 宿主机与容器之间的文件拷贝 引言 xff1a 利用MySQL镜像安装MySQL服务 从容器中拷贝文件到宿主机 从宿主机拷贝文件到容器 数据卷 数据卷容器 Dockerfile自定义镜像 自定义tomcat8 xff08 熟悉几乎所有的
  • Flask-SQLAlchemy 中的 relationship & backref

    今天重看 Flask 时 xff0c 发现对backref仍然没有理解透彻 查阅文档后发现 xff0c 以前试图孤立地理解backref是问题之源 xff0c backref是与relationship配合使用的 一对多关系 db rela
  • C++ 文件的读写(fin && fout)

    如何让键盘输入字符保存在 txt文件中 如何让我们自己在键盘上输入的字符不仅仅在屏幕上显示 xff0c 而且还能保存在特定路径的文件中 xff0c 这让简单枯燥的控制台命令程序变得略有趣 首先 xff0c 先看看cin和cout对象 xff

随机推荐