深拷贝、浅拷贝的方法

news2024/11/26 16:32:52

目录

浅拷贝

深拷贝


与浅拷贝概念: 

深浅拷贝出现的前提: 应用类型的数据(对象和数组)
深拷贝就是把目标对象里面的数据一个一个都复制下来,创建出一个一模一样的,存放地
址不一样,互不影响。就像真假美猴王。改变其中一个对象中的内容,另一个对象不会受
到任何影响。
浅拷贝就是单纯的复制内存地址,并没有复制对象本身,新旧两个都共享同一个内存。一荣
俱荣一损共损的样子,任何一个对象里改变某一个属性值,那么另一个也会随之发生改变
**区别:**浅拷贝只能复制第一层,想要深度拷贝的话就要用到深拷贝了

接下来我们就以下面这个obj1对象为例子,进行深浅拷贝的演示

  const obj1 = {
    a: 1,
    b: undefined,
    arr: [1, 2, 3],
    fun: () => {}
  }

浅拷贝

1.Object.assign()方法

const obj2 = Object.assign({},obj1)


 

缺点:这里就会发现使用Object.assign()只能深拷贝一级属性,二级以上的属性(引用类型)就是浅拷贝了

2.扩展运算符

const obj2 = {...obj1}

 

 

缺点:这个方法和上面使用Object.assign()方法使用的结果都是一样的。只能深拷贝一级属性,二级以上属性(引用类型)就是浅拷贝了

深拷贝

1.写一个递归(推荐,比较完美的解决方案)
封装一个DeepClone的深拷贝函数

  function DeepClone(data) {
    const newData = Array.isArray(data) ? [] : {}
    for (let key in data) {
      if (data[key] && typeof data[key] === 'object') {
        newData[key] = DeepClone(data[key])
      } else {
        newData[key] = data[key]
      }
    }
    return newData
  }

//调用他

const obj2 = DeepClone(obj1)

 2.用for…in实现遍历和复制

function deepClone(obj) {
    let result = typeof  obj.splice === "function" ? [] : {};
    if (obj && typeof obj === 'object') {
        for (let key in obj) {
            if (obj[key] && typeof obj[key] === 'object') {
                result[key] = deepClone(obj[key]);//如果对象的属性值为object的时候,递归调用deepClone,即在吧某个值对象复制一份到新的对象的对应值中。
            } else {
                result[key] = obj[key];//如果对象的属性值不为object的时候,直接复制参数对象的每一个键值到新的对象对应的键值对中。
            }

        }
        return result;
    }
    return obj;
}

let testArray = ["a", "b", "c", "d"];
let testRes = deepClone(testArray);
console.log(testRes);
console.log(typeof testRes[1]);

let testObj = {
    name: "weiqiujuan",
    sex: "girl",
    age: 22,
    favorite: "play",
    family: {brother: "son", mother: "haha", father: "heihei"}
};
let testRes2 = deepClone(testObj);
testRes2.family.brother = "weibo";
console.log(testRes2);

3.利用数组的Array.prototype.forEach进copy

let deepClone = function (obj) {
       //Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。
        let copy = Object.create(Object.getPrototypeOf(obj));
        //**Object.getOwnPropertyNames()**方法返回一个由指定对象的所有自身属性的属性名
        //(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。
        let propNames = Object.getOwnPropertyNames(obj);
        propNames.forEach(function (items) {
          // 方法返回指定对象上一个自有属性对应的属性描述符。
          //(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
          let item = Object.getOwnPropertyDescriptor(obj, items);
          Object.defineProperty(copy, items, item);
        });
        return copy;
};

let testObj = {
    name: "weiqiujuan",
    sex: "girl",
    age: 22,
    favorite: "play",
    family: {brother: "wei", mother: "haha", father: "heihei"}
}
let testRes2 = deepClone(testObj);
console.log(testRes2);

 

4.JSON转换方法

  const obj1 = {
    a: 1,
    b: undefined,
    arr: [1, 2, 3],
    fun: () => {}
  }
const obj2 = JSON.parse(JSON.stringify(obj1)) 

//这个方法可以,只不过function和undefined这种情况下无法复制

缺点:你看到这里就会发现数据类型是 function 和 undefined 情况下无法复制,其他的都可以进行深层次的拷贝

5.loadash函数库
函数库lodash,也有提供_.cloneDeep用来做深拷贝6.

let lodash = require('lodash');
let list = [{ name: 'Tom' }];
let copyList = lodash.cloneDeep(list);
copyList[0].name = 'Jerry'
console.log(list[0].name);      // Tom
console.log(copyList[0].name);      // Jerry

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/51963.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【白嫖】如何底价续费服务器

目录 背景 问题 缓解方案 背景 现在各大云服务商的学生价服务器都已经关闭了,华为云、阿里云、百度云,以前都有学生价服务器,一年只要99。现在我找半天都没找到入口,而原价的一年得500块起步。。。 但是!&#xff0…

MySQL事务详解

目录 引例 什么是事务 一个完整事务所具有的四大属性 为什么会出现事务 事务常见操作方式 事务隔离级别 为什么要存在隔离级别 一致性 引例 如下图,是一个火车售票系统,当客户端A发现还有一张票时,将票卖掉,还没执行更新…

C++实现UDP可靠传输(二)

声明:禁止以任何形式转载本文章。本文章仅供个人学习记录与交流探讨,文章中提供的思路只是一种解决方案,代码也并非完整代码,如有需要,请自行设计协议并完成编程任务。 食用本文章之前,推荐阅读&#xff…

RKMEDIA--VENC/VDEC使用

前面两篇已经介绍了VI和VO的使用,本章节来介绍rkmedia且也是瑞芯微平台重点部分:编解码。 目录 一、简介 二、编解码能力 三、编码 编码初始化: 在初始化VENC时需要注意几点: venc编码帧率控制: 编码添加osd位图…

软件设计师考试重点1 计算机组成与体系结构

软件设计师考试重点1 计算机组成与体系结构一、 数据的表示1. 进制转换2. 原码/反码/补码/移码3. 数值表示范围4. 浮点数的运算二、运算器与控制器1. 计算机结构2. 计算机五大组成部分:3. CPU组成部分:4. 控制器组成部分:5. 运算器组成部分&a…

如何构建一个自动化油田注水站监控系统?

一、应用背景 目前,在大部分的钻井平台中,维护油田注水站的工作状态主要通过人工方式进行,这种方式不仅作业效率低且对工人的经验有着较高要求。此外,油田注水站的工作环境恶劣,为了能够有效地掌握各个设备的工作状态…

【测试沉思录】20. 如何做好测试需求分析?

作者:刘亚茹 编辑:毕小烦 我们都知道测试用例是软件测试中保障质量的必要手段,而测试需求作为用例编写的主要依据却往往被很多人忽视。到底什么是测试需求?又如何做好测试需求分析呢?本文带你了解一下。 1. 测试需求到…

Java项目如何导出数据为 PDF 文件?

文章目录Java项目如何导出数据为 PDF 文件?一、代码结构如下二、代码说明1、添加依赖 pom.xml3、添加字体4、PDF 导出工具类三、效果图结语Java项目如何导出数据为 PDF 文件? 一个小需求,需要将页面上的数据导出为PDF,正常情况下…

11月业务安全月报 | 台湾2300万人信息泄露;黑客两分钟即可破解安卓锁屏;乌克兰“IT军团”入侵俄罗斯中央银行

导语:随着数字化的深入普及,业务愈加开放互联。企业的关键数据、用户信息、基础设施、运营过程等均处于边界模糊且日益开放的环境中,涉及利益流和高附加值的业务面临多样的安全隐患,随时可能遭遇损失,进而影响企业运营…

Android 8.0网络DNS

1 Linux DNS规范 Linux上并没有一个单独的方法可以完成DNS查询工作;没有一个有这样的明确接口的核心系统调用system call。不过,glibc (nss)的getaddrinfo (3), gethostbyname (3)等相关API (RFC3493)提供了DNS查询功能。 1)不支持nscd&#…

关于使用STM32CubeMx配置串口出现的一些问题

一、使用CubeMX配置好串口中断的工程,打开工程添加相关代码后串口没有数据输出或者看不见数据但串口助手的RX会一直增加的问题。 参考:这里 大概意思就是时钟的原因,需要把stm32f4xx_hal_conf.h文件中的时钟改一下,将25MHz改为8…

Ansys Zemax | 使用 OpticStudio 进行闪光激光雷达系统建模(中)

在消费类电子产品领域,工程师可利用激光雷达实现众多功能,如面部识别和3D映射等。尽管激光雷达系统的应用非常广泛而且截然不同,但是 “闪光激光雷达” 解决方案通常都适用于在使用固态光学元件的目标场景中生成可检测的点阵列。凭借具有针对…

我要涨知识——TypeScript 经典高频面试题(二)

又是一个年底来了,好大一批人可能又准备跑路了,翻了翻掘金和 CSDN 发现好多大佬都有大厂 Offer ,看着看着我心动了! 话不多说,赶紧开干,给自己整了一个前端面试小助手——微信小程序内搜索 “WEB学习学习加…

jar启动指定JDK/JRE 安装路径教程

前言 因为疫情在家办公的缘故,有个老项目,需要改个接口,然后需要前端联调,因为外网服务器没有多余的空间了,想着把jar给前端让前端开发人员,在自己的本机启动后端服务,进行接口联调,…

streptavidin-PEG-6-FAM 链霉亲和素-聚乙二醇-6-羧甲基荧光素

产品名称:链霉亲和素-聚乙二醇-6-羧甲基荧光素 英文名称:streptavidin-PEG-6-FAM 纯度:95% 存储条件:-20C,避光,避湿 外观:固体或粘性液体,取决于分子量 PEG分子量可选:350、550、75…

虚拟内存系统【如何支持巨大的虚拟地址空间】

如何支持巨大的虚拟地址空间📖1. 为什么要支持巨大的虚拟地址空间📖2. 交换空间📖3. 存在位📖4. 页错误📖5. 为了处理页错误,操作系统大致做了什么?📖6. 页面换出📖7. 当…

IDEA 中使用 SparkSQL 远程连接 Hive

文章目录第一步,环境配置第二步,IDEA 配置第三步,授权第四步,连接测试扩展——华为云/阿里云集群报错第一步,环境配置 首先,你要确保你的集群可以正常运行。 我们在 Windows 电脑中安装 Hadoop&#xff0…

【新知实验室--音视频通话】腾讯云TRTC-实时音视频---多人会议视频通话SDK基础搭建

🦖我是Sam9029,一个前端 Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主 🐱‍🐉🐱‍🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求收…

基于STM32单片机的篮球计时记分器proteus仿真原理图PCB

功能: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示比赛剩余时间,球队分数 2.默认计时器为4节,每节10分钟,每节比赛结束,蜂鸣器报警 3.按键功能介绍: 1’键——加1分 4’键——减1分 2’键——加2分 5’键—…

基于java+springmvc+mybatis+vue+mysql的水果食品果蔬生鲜商城销售系统

项目介绍 网络购物作为一种全新的销售方式赢得了越来越多销售者的青睐,近年来销售额更是以连年翻番的惊人速度成倍增长,网络购物已经形成了自身特有的网络销售市场和全新的网络营销模式,也使网络营销渠道应运而生,同时&#xff0…