每日一题之深浅拷贝总结

C++每日一练(拷贝构造函数、友元函数) 一、今日课题1.拷贝构造函数2.友元函数二、实战演练1.拷贝构造函数 拷贝构造函数,又称复制构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。 其唯一的形参必须是引用,但并不限制为const,一般普遍的会加上const限制。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常 阅读详情

已经写过 n次了, 再记录一遍吧

深浅拷贝

浅拷贝

一个新的对象对原始对象的属性值进行精确地拷贝,如果拷贝的是基本数据类型,拷贝的就是基本数据类型的值,如果是引用数据类型,拷贝的就是内存地址。如果其中一个对象的引用内存地址发生改变,另一个对象也会发生变化。

let arr = [12, 2, 3];
let arr2 = arr;
arr[0] = arr[0] + 1;
console.log("arr2 :>> ", arr2);
console.log("arr :>> ", arr);
console.log("arr === arr2 :>> ", arr === arr2); // true
  • Object.assign

    可以理解成用于 JS对象的合并, 其中一个用途就是浅拷贝, 该方法接受多个参数, 第一个参数是目标对象, 其余参数是源对象 Object.assign(target, source, source2)

    注意:

    • 如果目标对象和源对象有同名属性, 或者多个源对象有同名属性, 则后面的属性会覆盖前面的属性
    • 如果只有一个参数, 当参数为对象时, 直接返回该对象, 当参数不是对象时, 会先将参数转为对象然后返回
    • 如果第一个参数为null或者undefined, 将会报错
    • 不会拷贝对象的继承属性, 不会拷贝对象的不可枚举的属性, 可以拷贝Symbol类型的属性
let targetObj = {
  name: "lm",
  age: 22,
  sex: 0,
};
let obj = {
  name: "dzl",
};
let obj2 = {
  name: "世界",
};

Object.assign(targetObj, obj, obj2);
console.log("targetObj :>> ", targetObj);
// {name: '世界', age: 22, sex: 0} 可以看到name被覆盖

let targetObj2 = { ...targetObj };
targetObj.job.key = "web前端";
targetObj.age = 18;
console.log("targetObj.age = 18 :>> ");
console.log("targetObj.job.key = 'web前端'");
console.log("targetObj :>> ", targetObj);
// {
//   age: 18,
//   job: { key: 'web前端', key2: '后端'},
//   name: '世界',
//   sex: 0
// }
console.log("targetObj2 :>> ", targetObj2);
// {
//   age: 22,
//   job: { key: 'web前端', key2: '后端'},
//   name: '世界',
//   sex: 0
// }

// 可以看到基本数据类型是深拷贝, 引用类型则是浅拷贝

  • Array.prototype.slice

    • 该方法会复制出一个副本, 也就是说不会改变原数组
    • 用法: arr.slice(start, end), 参数都不填意味着全复制
let arr = [1, 2, 3, 4, 5];
let arr1 = arr.slice();
arr1[0] = 0;
console.log("arr3 :>> ", arr3); // arr3 :>>  (5) [0, 2, 3, 4, 5]
console.log("arr4 :>> ", arr4); // arr4 :>>  (5) [1, 2, 3, 4, 5]
  • Array.prototype.concat

    • 该方法会返回一个新的数组, 也就是说不会改变原数组
    • 用法: arr.concat(array), 参数都不填意味着全复制
let arr = [1, 2, 3, 4, 5];
let arr1 = arr.concat();
arr1[0] = 0;
console.log("arr3 :>> ", arr3); // arr3 :>>  (5) [0, 2, 3, 4, 5]
console.log("arr4 :>> ", arr4); // arr4 :>>  (5) [1, 2, 3, 4, 5]
console.log("arr4 === arr3 :>> ", arr4); // false

深拷贝

对于简单数据类型直接拷贝值, 对于引用数据类型, 在堆内存中开辟一块新的内存用于存放复制的对象, 两个对象相互独立, 属于不同的内存地址

  • Object.assign

Object.assign 拷贝的对象的属性值只是简单类型(number, boolean, string);
得到的新对象的属性值是深拷贝,
如果属性值是对象或者其他引用类型,
那么拷贝的这个属性值是浅拷贝

const data = {
  name: "dzl",
  age: 20,
  job: {
    job1: "web",
    job2: "back",
    job3: {
      key: "嘻嘻",
    },
  },
};

let newObj = Object.assign({}, data);
newObj.age = 30;
newObj.job.job1 = "哈哈哈哈哈";
console.log("data :>> ", data);
// {
//   age: 20,
//   job: { job1: '哈哈哈哈哈', job2: 'back', job3: {...} },
//   name: 'dzl'
// }
console.log("newObj :>> ", newObj);
// {
//   age: 30,
//   job: { job1: '哈哈哈哈哈', job2: 'back', job3: {...} },
//   name: 'dzl'
// }
  • JSON.parse(JSON.stringify(cloneObj))

    通过JSON进行序列化反序列化可以实现深拷贝, 但是会存在几个问题

    • 会自动忽略拷贝对象中的函数
    • 对日期的半支持(如传入 GMT+0800 时间), 输出 ISO 8601 时间
    • 会忽略undefined类型
    • 会忽略 key 为 symbol类型的字段
    • 无法保持之前的原型链
    • 拷贝 RegExp 引用类型会变成空对象
    • 对象中包含 NaN, Infinity, 或 -Infinity, 结果会变成 null
const b = {
  name: "dzl",
  age: 20,
  fn: undefined,
  date: new Date(), // Mon Jun 20 2022 11:21:08 GMT+0800 (中国标准时间) {}
};

const b1 = JSON.parse(JSON.stringify(b));
console.log(b1);
// {
//   age: 20,
//   name: "dzl",
//   date: "2022-06-20T03:21:08.213Z", ISO 8601 国际标准化组织的国际标准
// }
  • 手写深拷贝
function cloneDeep(target, map = new map()) {
  if (target === null) return null;
  if (typeof target !== "object") return target;
  // 处理正则, Date类型
  if (target.constructor === Date) return new Date(target);
  if (target.constructor === RegExp) return new RegExp(target);

  // 处理对象内的循环引用1
  if (map.has(target)) return map.get(target);

  // 保持之前的原型链
  const newTarget = new target.constructor();
  // 没有保持原型链判断
  // const newTarget = Array.isArray(target) ? [] : {}

  // 处理对象内的循环引用2
  map.set(target, newTarget);

  // for .. in .. 遍历不到Symbol类型的key, 这里使用 Reflect.ownKeys方法, 它可以遍历当前对象的所有key
  // for(let key in target) {
  //   if (target.hasOwnProperty(key)) {
  //     newTarget[key] = cloneDeep(target[key])
  //   }
  // }

  Reflect.ownKeys(target).forEach((key) => {
    // newTarget[key] = cloneDeep(target[key])
    // 处理对象内的循环引用3
    newTarget[key] = cloneDeep(target[key], map);
  });

  // 处理对象内的循环引用使用Map即可
  return newTarget;
}

浅拷贝总结:

  • Object.assign(target, source, source2)

    • 如果目标对象和源对象有同名属性, 或者多个源对象有同名属性, 则后面的属性会覆盖前面的属性
    • 如果只有一个参数, 当参数为对象时, 直接返回该对象, 当参数不是对象时, 会先将参数转为对象然后返回
    • 如果第一个参数为null或者undefined, 将会报错
    • 不会拷贝对象的继承属性, 不会拷贝对象的不可枚举的属性, 可以拷贝Symbol类型的属性
  • Array.prototype.slice

  • Array.prototype.concat

深拷贝总结:

  • JSON.parse(JSON.stringify(cloneObj))

    通过JSON进行序列化反序列化可以实现深拷贝, 但是会存在几个问题

    • 会自动忽略拷贝对象中的函数
    • 对日期的半支持(如传入 GMT+0800 时间), 输出 ISO 8601 时间
    • 会忽略undefined类型
    • 会忽略 key 为 symbol类型的字段
    • 无法保持之前的原型链
    • 拷贝 RegExp 引用类型会变成空对象
    • 对象中包含 NaN, Infinity, 或 -Infinity, 结果会变成 null
  • lodash.deepClone

  • 自己写一遍

保姆级教程:在Zynq UltraScale+ EV系列FPGA上,用VCU IP核搞定4K60帧H265视频解码与HDMI2.0输出 本文提供在Zynq UltraScale+ EV系列FPGA上使用VCU IP核实现4K60帧H265视频解码与HDMI2.0输出的全流程指南。从开发环境准备、Vivado工程配置到PetaLinux系统定制,详细解析硬件选型、IP核参数设置及性能优化技巧,帮助开发者快速构建高效视频处理系统。 阅读详情

相关推荐

PHP实战:5分钟搞定SM4国密加密算法集成(附完整代码)

本文详细介绍了如何在PHP项目中快速集成SM4国密加密算法,提供完整的代码实现和实际应用示例。从算法原理到核心代码解析,再到性能优化与安全实践,帮助开发者高效实现数据加密功能,满足金融、政务等领域的合规需求。

weixin_29315569的博客 353

Python的深浅拷贝讲解!

↑↑↑关注后"星标"Datawhale每日干货&每月组队学习,不错过 Datawhale干货作者:皮钱超,厦门大学,Datawhale原创作者本文约3000...

Datawhale 295

ERA5获取的风场数据转换为.dfs2文件

ERA5获取风场数据的具体步骤可以参考下面的文章下载好后应该是.nc格式的文件,想要读取或者转换成其他格式的文件可以安装下面步骤,本文介绍如何转换为.dfs2文件。

我的博客 1459

每日一课 | list 和 tuple 的基本操作、深浅拷贝和切片操作详细等 5 个方面总结

02大家好,我是营长,上期营长分享了“详解Python四大数据类型”,这期营长接着为大家分享Python相关内容。本期分享内容:List和 tuple的基本操作这期分享营长邀请的是zglg...

Python大本营的博客 7497

AI Agent实战:WorkBuddy安装部署、任务执行与模型接入全教程

AI Agent是当前自动化办公与智能工作流的核心技术,它区别于传统问答式AI,能够理解目标、拆解任务并调用工具交付完整成果。其底层原理基于任务规划、工具调用与结果验证的循环机制,让机器从“提供建议”进化为“完成任务”。在工程实践中,合理配置模型服务(如接入DeepSeek)、设计标准化Skill(技能包)与自定义指令,可以显著提升Agent在报告生成、数据分析、竞品调研等场景中的稳定性与效率。WorkBuddy作为典型的任务式AI工作台,为运营、产品、开发等多角色提供了统一入口,覆盖安装部署、任务描述公式

weixin_26712075的博客 289

图像修复黑科技:对比BM3D/DnCNN等5种去噪器在PNP框架中的实战效果

本文深度评测了BM3D、DnCNN等五款主流去噪器在即插即用(PnP)优化框架中的实战表现。通过量化指标、视觉对比及超分等泛化任务测试,揭示了深度学习模型在性能与收敛速度上的优势,并为不同应用场景提供了选型指南与工程化建议。

weixin_29065959的博客 366

python 实例对象 浅拷贝_Python的深浅拷贝讲解!

原标题:Python的深浅拷贝讲解!Datawhale & LSGO软件技术团队每日干货 &每月组队学习 ,不错过Datawhale干货作者:皮钱超,厦门大学,Datawhale原创作者本文约3000字,建议阅读9分钟审稿人:耿远昊,Datawhale成员,华东师范大学,开源教程《Joyful-Pandas》核心贡献者。前言在很多语言中都存在 深浅拷贝两种拷贝数据的方式,Pytho...

weixin_39531229的博客 182

PicoRV32 笔记 05

PicoRV32 本地总线接口

jjinl的专栏 1573

python 嵌套引用_Python的深浅拷贝讲解!

↑↑↑关注后"星标"Datawhale每日干货&每月组队学习,不错过 Datawhale干货作者:皮钱超,厦门大学,Datawhale原创作者本文约3000字,建议阅读9分钟审稿人:耿远昊,Datawhale成员,华东师范大学,开源教程《Joyful-Pandas》核心贡献者。前言在很多语言中都存在深浅拷贝两种拷贝数据的方式,Python中也不例外。本文中详细介绍了Pyth...

weixin_30591519的博客 252

W5500+STM32F103C8T6进行TCP通信(modbus)

一路生花一、w5500资料二、modbus通信三、从机代码四、总结五、参考 一、w5500资料 w5500的资料就放在下面了,单纯的客户端和其他模式上面有教程 https://www.aliyundrive.com/s/enPnnZgNtpE 二、modbus通信 Modbus RTU通信时使用的数据帧结构如下图,而Moubus TCP通信的数据帧和这个稍微不一样,没有crc检验,因为tcp本就是一种可靠传输协议 这里是Modbus TCP数据帧 公共功能码定义 三、从机代码

junseven164的博客 5777

基于CRU和WorldClim的高分辨率(1km)气候数据生成

基于CRU和WorldClim的高分辨率(1km)气候数据生成

lhq7842955的博客 1691

python 追加到字典_Python的深浅拷贝讲解!

↑↑↑关注后"星标"Datawhale每日干货&每月组队学习,不错过 Datawhale干货作者:皮钱超,厦门大学,Datawhale原创作者本文约3000字,建议阅读9分钟审稿人:耿远昊,Datawhale成员,华东师范大学,开源教程《Joyful-Pandas》核心贡献者。前言在很多语言中都存在深浅拷贝两种拷贝数据的方式,Python中也不例外。本文中详细介绍了Pyth...

weixin_30533377的博客 228

YOLOv11改进策略【模型轻量化】| 替换骨干网络 CVPR-2024 RepViT 轻量级的Vision Transformers架构

本文记录的是基于RepVit的YOLOv11轻量化改进方法研究。RepVit的网络结构借鉴ViT的设计理念,通过分离的token mixe和减少推理时的计算和内存成本,同时减少扩展比率并增加宽度,降低延迟,并通过来弥补参数大幅减少的问题,提高了准确性。本文在替换骨干网络中配置了原论文中的和五种模型,以满足不同的需求。

Limiiiing的博客 2973

每日进步一点点(数组练习)

文章目录前言一、数组练习1.交换两个数的值二、使用步骤1.引入库2.读入数据总结前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 在本章中,主要写在学习过程中数组的诸多例题。 一、数组练习 1.交换两个数的值 在没有学数组之前,是无法使用方法来进行交换数组的值的。 原因:传参时,两个进行交换的作用域不同,故无法交换 在数组中使用则可以 进行交换。 在数组传参时,传过去堆上的地址可以直接改变原来的数据 public static void main(String[] args) {

m0_50976823的博客 124

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

07.29&07.30每日总结

C语言:结构体收尾 typedef 线性代数:线性方程组的几何意义 矩阵消元 mysql:多对多关系型数据库数据表的创建和练习

A2583591687的博客 250

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Python中怎么解决GIL锁与深浅拷贝问题【详细】

与python中GIL锁与深浅拷贝的知识与操作方法看这一篇文章就够啦

大学生活与学习一站式解决方案. 1040

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

python可变类型和不可变深浅拷贝类型_Python的深浅拷贝讲解!

↑↑↑关注后"星标"Datawhale每日干货&每月组队学习,不错过 Datawhale干货作者:皮钱超,厦门大学,Datawhale原创作者本文约3000字,建议阅读9分钟审稿人:耿远昊,Datawhale成员,华东师范大学,开源教程《Joyful-Pandas》核心贡献者。前言在很多语言中都存在深浅拷贝两种拷贝数据的方式,Python中也不例外。本文中详细介绍了Python中的深...

weixin_39705435的博客 181

IOS学习之深浅拷贝

坚持 成长 每日一篇 以下是自己对深浅拷贝的理解,如果有错误望指出,感激不尽 浅拷贝:把对象的地址进行拷贝,没有开辟新的内存(也就是没有产生新的对象) 深拷贝:把对象进行的复制,开辟了新的内存,产生了新的对象 下面我们对系统自带类的copy和mutableCopy对象进行分析对于不可变字符串:copy是浅拷贝,mutableCopy是深拷贝 NSString *string =

chirs的专栏 486

是时候捋一捋Java的深浅拷贝了

点击上方IT牧场,选择置顶或者星标技术干货每日送达在开发、刷题、面试中,我们可能会遇到将一个对象的属性赋值到另一个对象的情况,这种情况就叫做拷贝。拷贝与Java内存结构息息相关,搞...

ITMuch的专栏 107

求职无忧之 JavaScript 每日 3 道 面试题

只能克隆最外层数据,内层数据还会共享同一个数据地址一、对象浅拷贝: 1 、遍历原对象将所有键值对放在新对象中 -- -- -- 遍历 2 、利用Object . assign(新对象 , 原对象) -- -- -- - assign方法复制 3 、 var 新对象 = {... 原对象 } -- -- -- 扩展运算。

2301_76661908的博客 219

每日五题--new,对象的深浅拷贝,发布订阅,instanceof、防抖节流

防抖:执行了防抖定时器,如果在这个时间范围内触发了第二次,就会清空之前的定时器,重新定时,只有这个时间范围不再触发这个操作,到点了才会去执行定时器里面的代码。概念:浅拷贝是只拷贝最外层的值,所以原对象值的改变会影响到拷贝后的对象;而深拷贝则是拷贝对象最里层的值,所以原对象值的改变是不会影响到拷贝后的对象的;object instanceof 构造函数,instanceof是判断对象的原型链上是否有构造函数的原型对象。发布订阅是一种常见的组件通信的模式,发布了一条消息,所有订阅了这条消息的函数都会被执行。

m0_51591940的博客 99

每日一课 | List和 tuple的基本操作

04.list和tuple的基本操作大家好,我是小C,上期给大家分享带来——Python的四大数据类型本期分享内容:List和 tuple的基本操作本专栏小C邀请的是zglg(某大厂算法...

sinat_32849897的博客 220

每日八股文5.31

因为在go的底层map的实现是一个哈希表,当要往map里面存储新的元素时,会为每一个键计算一个哈希值,而这个哈希值在内存中不一定是连续的;另外当map进行扩容时,所有在map中存储的元素都会重新计算一遍哈希值,所以多次遍历同一个map,结果不一定是相同的。

weixin_50927943的博客 1275

每日一结(10.24)

1.字面量创建2.使用new关键字创建3.获取数组中的内容 数组[下标] 下标是从0开始//"1"4.通过下标的添加 数组[下标] = 值arr1[3] = "哈哈";//["1","2","3".'哈哈']5.注意事项(1):使用new关键字创建数组的时候 如果创建元素只有1个并且是number类型,意味着创建length值为n的空属性(2):arr1.属性名 = 属性值。

xz100599的博客 486

python深浅拷贝原理_Python深浅拷贝图解

作者 koyo | 来源 Openskill 糖豆贴心提醒,本文阅读时间6分钟,文末有秘密!Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果。下面本文就通过简单的例子介绍一下这些概念之间的差别。1.对象赋值直接看一段代码: 代码的输出为: 下面来分析一下这段代码:首先,创建了一个名为will的变量,这个变量指向一个list对象,从第一张图中...

weixin_39760689的博客 181

Java中的深浅拷贝问题你清楚吗?

点击上方IT牧场,选择置顶或者星标技术干货每日送达一、前言拷贝这个词想必大家都很熟悉,在工作中经常需要拷贝一份文件作为副本。拷贝的好处也很明显,相较于新建来说,可以节省很大的工作量...

ITMuch的专栏 148
上一篇: 每日一题之实现瀑布流
下一篇: node.js小知识-对文件中图片归类
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值