浅谈深拷贝与浅拷贝

news2024/11/13 10:02:37

一、拷贝(克隆)的意义的场景

意义:保证原数据的完整性和独立性
常见场景:复制数据、函数入参、class构造函数

二、浅拷贝

  • 只克隆对象的第一层级
  • 如果属性值是原始数据类型,拷贝其值,即:值拷贝
  • 如果属性值是引用类型,拷贝其内存地址,即:引用拷贝

1、ES6拓展运算符 … / slice(0) / [ ].concat

const sourceObject = { foo: [1, 2, 3], bar: { x: 10, y: 20 } };
const copiedObject = { ...sourceObject };

copiedObject.foo.push(4);
copiedObject.bar.z = 30;

console.log(sourceObject.foo); // Output: [1, 2, 3, 4] (原对象也被修改)
console.log(sourceObject.bar); // Output: { x: 10, y: 20, z: 30 } (原对象也被修改)

// 数组的浅拷贝
const arr = [1, 2, 3]
const arr2 = [...arr]
const arr3 = arr.slice(0)
const arr4 = [].concat(arr)

2、Object.assign()

const target = {};

const source1 = { foo: 1 };
const source2 = { bar: 2, aaa: {bbb: 666}};

Object.assign(target, source1, source2);

3、for…in…和其它的一层遍历复制

const source = { foo: 1, bar: 2 };
const target = {};

for (const key in source) {
  target[key] = source[key];
}

console.log(target);
// Output: { foo: 1, bar: 2 }

const source = { foo: 1, bar: 2 };
const target = {};

for (const key in source) {
  if (source.hasOwnProperty(key)) {
    target[key] = source[key];
  }
}

console.log(target);
// Output: { foo: 1, bar: 2 }

这样可以确保只复制对象自身的属性,而不包括继承的属性。

需要注意的是,for...in 循环不会复制对象的方法,只会复制属性。
如果要复制对象的方法,可以使用其他方法或库来实现更复杂的拷贝,比如深拷贝。

三、深拷贝

  • 克隆对象的每个层级
  • 如果属性值是原始数据类型,拷贝其值,即:值拷贝
  • 如果属性值是引用类型,递归克隆

1、JSON.parse(JSON.stringify( obj ))

  • 只能复制普通键的属性,Symbol类型的无能为力
  • 循环引用对象,比如 window无法复制
  • 函数 Date Rege Blob等类型不能复制
  • 性能差
function clone(obj) {
	return JSON.parse(JSON.stringify(obj))
}
const a = clone({
	a: 1,
	b: { c: 2 }
})
console.log('a:', a)

// 时间: 转为字符串
console.log('date:', clone({date:new Date()}))

// 正则: 变成空对象   异常
console.log('regex:', clone({regex:/[0-9]/}))

// Blob: 变成空对象   异常
console.log('blob:', clone({blob:new Blob(['123'])}))

// 函数
console.log('function:', clone({fn(){}})) // {}

// window
console.log('function:', clone(window)) // Uncaught TypeError: Converting circular structure to JSON

在这里插入图片描述

2、消息通讯BroadcastChannel

  • 循环引用对象不能复制, 如 window
  • 函数不能复制
  • 同步变成异步
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

3、手写简单版深拷贝

在这里插入图片描述
上面的方法 如果在数组中添加了非数字属性就会出问题

在这里插入图片描述

在这里插入图片描述

4、浅拷贝 vs 深拷贝

在这里插入图片描述

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

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

相关文章

anaconda切换python版本

1 查看环境 conda env list结果如下图,左侧表示已下载的环境信息,当前我已经下载了python3.10(python310)和3.9(python39)两个版本 2 切换python版本 conda activate python3103 下载python # 下载pyt…

【玩转pandas系列】巧妙处理某瓣电影top250空数据

向阳花花花花 - 个人主页 迄今所有人生都大写着失败,但并不妨碍我继续向前 Python 数据分析专栏 正在火热更新中 🔥 文章目录 前言一、处理某瓣电影top250空数据二、对于空值,有没有别的处理办法?三、上述案例总结3.1 查看数据信…

个人博客系统 -- 博客列表页删除Markdown字符

之前的博客系统的列表页会有在markdown编辑器中的特殊字符,比如标题的字符#之类的,在列表页进行展示的时候,我们需要将这些字符进行筛选. 对这些字符进行筛选,我们可以通过排设计正则表达式进行筛选,也可以使用组件的方式进行筛选.下面我来总结一下,使用组件的方式进行筛选. 这…

Codeforces Round 886 (Div. 4)F题解

文章目录 [We Were Both Children](https://codeforces.com/contest/1850/problem/F)问题建模问题分析1.分析到达的点与跳跃距离的关系2.方法1倍数法累计每个点所能达到的青蛙数代码 方法2试除法累计每个点能到达的青蛙数代码 We Were Both Children 问题建模 给定n个青蛙每次…

Mac平台首选原生轻量级的嵌入式数据库引擎:Native SQLite Manager for Mac

亲爱的读者,如果你是一位在Mac平台上使用SQLite数据库的开发者或数据分析师,那么本文将为你介绍一款非常实用的工具——原生SQLite管理器。 SQLite是一种轻量级的嵌入式数据库引擎,被广泛应用于各种应用程序和系统中。它具有高效、可靠和易于…

ThirdAI 的私有和可个性化神经数据库:增强检索增强生成(第 3/3 部分)

这是我们关于使用检索增强生成构建 AI 代理的系列的最后一章 (3/3)。在第 1/3 部分中,我们讨论了断开连接的嵌入和基于矢量的检索管道的局限性。在第 2/3 部分中,我们介绍了神经数据库,它消除了存储和操作繁重且昂贵的…

GitHub上怎么寻找项目?

前言 下面由我精心整理的关于github项目资源搜索的一些方法,这些方法可以帮助你更快更精确的搜寻到你需要的符合你要求的项目。 写文章不易,如果这一篇问文章对你有帮助,求点赞求收藏~ 好,下面我们直接进入正题——> 首先我…

接口测试必备的,2种常⽤的JSON解析⽅法

JSON简介 一、JSON是什么? JSON: JavaScript Object Notation JS对象简谱,是一种轻量级的数据交换模式。 二、JSON语法: 对象中通过键值对 (key: value)的形式来表示对象的属性 注意:value即可以表示属性变量,又可…

【数据结构(C++版)】哈希表(散列表)

目录 1. 散列表的概念 2. 散列函数的构造方法 2.1 直接定址法 2.2 除留余数法 2.3 数字分析法 2.4 平方取中法 3. 处理冲突的方法 3.1 开放定址法 3.1.1 线性探测法 3.1.2 平方探测法 3.1.3 双散列法 3.1.4 伪随机序列法 3.2 拉链法(链接法&#xff09…

数据结构---并查集

目录标题 为什么会有并查集并查集的原理模拟实现并查集准备工作构造函数FindRootUnionSetCount 并查集实战题目一:省份数量题目解析题目二:等式方程的可满足性题目解析 为什么会有并查集 这里可以使用生活中的一个例子来带着大家理解并查集,…

机器学习03-数据理解(小白快速理解分析Pima Indians数据集)

机器学习数据理解是指对数据集进行详细的分析和探索,以了解数据的结构、特征、分布和质量。数据理解是进行机器学习项目的重要第一步,它有助于我们对数据的基本属性有全面的了解,并为后续的数据预处理、特征工程和模型选择提供指导。 数据理解…

从Arweave开始:4EVERLAND存储签入挑战开始

嗨,4evers, 今天,我们热烈欢迎您参加 Galxe 上的 4EVERLAND “Arweave 入门”活动。这是一项长期的重头活动,所有参与的用户都有机会获得相应的奖励。 Arweave 是一种革命性的去中心化存储协议,为寻求安全可靠的有价…

基于飞桨paddle的极简方案构建手写数字识别模型测试代码

基于飞桨paddle的极简方案构建手写数字识别模型测试代码 原始测试图片为255X252的图片 因为是极简方案采用的是线性回归模型,所以预测结果数字不一致 本次预测的数字是 [[3]] 测试结果: PS E:\project\python> & D:/Python39/python.exe e:/pro…

第五章 数组

定义 数组是一组相同类型元素的集合,但我们需要创建多个相同类型的变量时,只需要创建一个类型的数组,就相当于同时创建很多相同类型的变量。 一维数组 数组如何创建 从定义来入手看一下数组的创建: type_t arr_name[const_n];…

《向量数据库指南》——FAISS和Chroma:两种流行的向量数据库的比较

目录 FAISS Chroma 比较 向量数据库是一种可以存储和检索高维向量数据的数据库,高维向量数据是一种可以表示任何类型数据的A.I原生方式,比如文本、图像、音频等。向量数据库可以用于实现各种基于相似度搜索和聚类的A.I应用,比如语义搜索、推荐系统、图像识别等。在本文中…

Spring Boot——Spring Boot自动配置原理

系列文章目录 Spring Boot启动原理 Spring Boot自动配置原理 系列文章目录前言一、Spring Boot自动配置原理剖析二、自动配置生效三、总结: 前言 一直在使用Spring Boot特别好奇的是为什么Spring Boot比Spring在项目构建和开发过程中要方便很多,无需编…

二叉树的层序遍历(两种方法:迭代+递归)

题目: 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 输入:root [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]] 解题思路:迭代法…

【设计模式——学习笔记】23种设计模式——组合模式Composite(原理讲解+应用场景介绍+案例介绍+Java代码实现)

案例引入 学校院系展示 编写程序展示一个学校院系结构: 需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系 【传统方式】 将学院看做是学校的子类,系是学院的子类,小的组织继承大…

位1的个数,编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1‘ 的个数(也被称为汉明重量)。

题记: 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。 提示: 请注意,在某些语言&#xff…

MySQL使用xtrabackup备份和恢复教程

1、xtrabackup说明 xtrabackup是percona开源的mysql物理备份工具。 xtrabackup 8.0支持mysql 8.0版本的备份和恢复。 xtrabackup 2.4支持mysql 5.7及以下版本的备份和恢复。 这里我以xtrabackup 8.0为例讲解备份和恢复的具体操作方法。 xtrabackup 2.4版本的使用上和8.0版本相…