浅拷贝和深拷贝(图文详解)

news2024/11/24 18:35:49

        前端面试中,面试官经常会提到关于浅拷贝和深拷贝的问题。但是我总是理解于它的表面,面试中再深挖一点就会卡壳,我想把我的理解写下来,希望可以帮助到大家,如果有错误的地方希望大家可以指正,以免误导~

看这篇文章之前,对于赋值的过程大家不了解的可以看我的这一篇文章https://blog.csdn.net/jisuaijicainiao/article/details/140844128?spm=1001.2014.3001.5501

浅拷贝的过程直接举例子说明能更加直观理解

首先说明一下浅拷贝的过程: 浅拷贝会创建一个新对象,并将原始对象的属性逐个复制到这个新对象中。然而,对于引用类型的属性(如对象、数组),浅拷贝只会复制引用,而不是复制引用类型的内容。

let obj1 = {
    'name':'Lili',
    'school':{
        'address':"北京"
    }
}
let obj2 = Object.assign({},obj1)
obj2.name = 'sasa'
obj2.school.address = '上海'
console.log(obj1.name)  //'Lili'
console.log(obj1.school.address)  //'上海'

       上面代码的过程通过图片显示就如下,在未改变obj2任何值之前,内存分配中做了这些操作。浅拷贝就是重新创建了一个对象,把被拷贝对象的属性值都放进了自己的对象中。对于引用类型,值也只是存储了引用地址。

       在改变obj2的属性值之后,如下图所示。因为obj2是在一个新的对象中,所以它的基本类型属性的修改不会影响到obj1。但是对于school属性,它是引用类型存储的是一个对象的地址,它跟obj1的school指向的是相同的一个对象。所以修改obj2就会影响到obj1的值。

 但是还有一种情况就是以下代码

let obj1 = {
    'name':'Lili',
    'school':{
        'address':"北京"
    }
}
let obj2 = Object.assign({},obj1)
obj2.name = 'sasa'
obj2.school = {address:'上海'}
console.log(obj1.name)  //'Lili'
console.log(obj1.school.address)  //'北京'

 图解的话就是下图这样的,obj2修改school属性的值,相当于重新创建了一个对象,在堆内存中重新开辟了一块空间,obj2对象的school属性指向新的对象地址。所以obj1和obj2此时不指向同一块空间,所以并不影响obj1对象。

        浅拷贝的实现方式除了Object.assign()方法【let obj2 = Object.assign({}, obj1)】,还有扩展运算符‘...’【let obj2 = {...obj1}】,还有Array.prototype.slice()通常用于数组拷贝【let arr2 = arr1.slice()】,还有Array.prototype.concat()用于数组拷贝【let arr2 = arr1.concat()】等等。

深拷贝

深拷贝的过程:深拷贝会递归的遍历对象的每个属性,如果属性是基本类型就会直接复制值,如果属性是引用类型,深拷贝就会创建一个新的对象或数组,并递归的复制其中的所有属性。深拷贝后的对象与原对象在内存上是完全独立的。

举例说明

let obj1 = {
  name:'Lili',
  school:{
      address:"北京"
  }
}
let obj2 = JSON.parse(JSON.stringify(obj1))

obj2.name = 'sasa'
obj2.school.address = '上海'
console.log(obj1.name)  //'Lili'
console.log(obj1.school.address)  //'北京'

上面代码的图解过程,根据上述深拷贝的过程,在修改拷贝对象的值之前我们可以得到下图的结果。obj1和obj2是两个完全独立的对象。

        当我们对obj2的属性值进行修改后,如下图所示。obj1是完全不受影响的,无论你怎么修改obj2的值都不会改变obj1的值。

 实现深拷贝的方法除了JSON.pares(JSON.stringify())外【let obj2 = JSON.pares(JSON.stringify())】,还有递归遍历手动复制实现,还可用lodash库的_.cloneDeep()方法【let obj2 = _.cloneDeep(obj1)】

今天就到这里吧~ 继续加油

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

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

相关文章

mysql的安装与初始化

mysql mysql5.7.40下载链接 mysql安装文档 1. 编译安装过程 yum install -y cmake # 安装cmake tar xf mysql-boost-5.7.40.tar.gz cd /root/mysql-5.7.40 cmake -LH # 查看cmake的默认参数,需要进入mysql目录 yum install -y gcc-c.x86_64 yum install -y bis…

漏洞挖掘 | 记一次伪静态页面的SQL注入

前言 最近工作繁忙,许久没有挖洞,打开度娘,凡事随缘,偶米头发~~(⊙﹏⊙) 涉及技能点 SQL注入基础原理 盲注常用函数及思路 burpsuite基础知识 过程记录 1.发现 在翻阅一EDU站点时,发现路径中带有明显的数字参数 …

Java语言程序设计基础篇_编程练习题*17.1 (创建一个文本文件)

题目:*17.1 (创建一个文本文件) 编写一个程序,如果文件 Exercise17_01.txt 不存在,就创建一个名为 Exercise17_01.txt 的文件。向这个文件追加新数据。使用文本 I/O 将 100 个随机生成的整数写入这个文件。文件中的整数用空格分隔。 习题思路…

Sqlite3数据库表内数据批量读取操作---sqlite3_stmt机制

0、引言 在前面两篇文章已经对数据环境搭建、数据批量写入库中进行了较为详细的讲解。因此,基于前两篇文章内容的基础上,本文主要从数据库中批量数据读取操作进行梳理讲解。 嵌入式数据库SQLite 3配置使用详细笔记教程_sqlite3-CSDN博客 SQLite 3 优化批…

TCP与UDP传输的学习

void *memset(void *s, int c, size_t n); 功能:将一块内存空间的每个字节都设置为指定的值;这个函数通常用于初始化一个内存空间,或者清空一个空间; 参数:viod * s 空类型指针,指向要填充内存块&#xf…

android13 隐藏状态栏里面的飞行模式 隐藏蓝牙 隐藏网络

总纲 android13 rom 开发总纲说明 目录 1.前言 2.问题分析 3.代码分析 4.代码修改 5.编译运行 6.彩蛋 1.前言 android13 隐藏状态栏里面的飞行模式,或者其他功能,如网络,蓝牙等等功能,隐藏下图中的一些图标。 2.问题分析 这里如果直接找这个布局的话,需要跟的逻…

ubuntu /windows 安装COLMAP

目录 一、COLMAP简介 二、ubuntu安装COLMAP 三、windows安装COLMAP 一、COLMAP简介 COLMAP 是一款用于3D重建和图像处理的软件,它结合了计算机视觉算法和优化技术,用于从一组图像中构建三维结构。COLMAP 是一个全功能的通用视觉测距和三维建模工具&a…

免费的AI认证考试

努力保持领先地位 过去几年,科技行业发展速度越来越快,尤其是人工智能和大型语言模型(LLM) 的出现。 作为该领域的资深软件开发人员,我也注意到一个人的经验很快就会变得过时。 就在几年前,神经网络和深度学习风靡一时。虽然这…

三星计划今年HBM4设计,2025年初开始样品测试

三星计划今年晚些时候完成首款HBM4内存设备的设计定稿,2025年初开始样品测试 根据nN Elec援引行业消息人士的报道,三星计划在今年晚些时候完成首款HBM4内存设备的设计定稿,并预计将于2025年初开始样品测试。该公司预计将采用其最新一代10纳米…

全新 Firebase AI 开发助手,助力构建应用的每一步

作者 / 助理产品经理实习生 Aayush Bandopadhyay 使用 Firebase 构建应用可以变得更加简单! 了解 Firebase 中的 Gemini,从构思应用创意到编写安全代码,都将成为您的最佳助手。这个功能强大的新工具集成在 Firebase 控制台中,可以…

如何在算家云搭建模型mPLUG-Owl3(智能对话)

一、模型介绍 1. 项目背景与概述 mPLUG-Owl3 是阿里巴巴 mPLUG 团队最新发布的通用多模态大模型,该模型在理解和处理复杂多图及长视频内容方面实现了显著突破。这一创新成果不仅提升了模型的推理效率,还保持了高度的准确性,为多模态大模型的…

计算机毕业设计选题推荐-花园管理系统-Java/Python项目实战

✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

Blender----利用DEM(tif)生成三维模型

首先需要安装Blender GIS这个插件:https://github.com/domlysz/BlenderGIS 一、TIFF的导入 可以通过GIS桌面端线查看DEM数据的信息,在blender中我们最好把TIF转换成3857或者其他投影的形式,推荐转成3857(web mector)投影是因为构建的模型可…

Leetcode-day31-01背包问题

46. 携带研究材料 1.dp数组代表的是什么? 这里的dp数组是一个二维数组,dp[i][j]是从前i个物品中任选放入容量j内的最大价值。 2.递推公式。 不放物品i:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值&am…

【时时三省】(C语言基础)数组参数

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 一维数组传参 一维数组传参 数组大小可以省略 也可以写成指针 如果这个一维数组是个指针数组 写成指针数组 或者写成二级指针 这个上面列的都是正确的写法 二维数组传参 第5行的写法是不行…

一条微博,让联想少卖16亿?

关注卢松松,会经常给你分享一些我的经验和观点。 万万没想到,联想起诉的第一个自媒体博主竟然是万能的大熊。 微博账号“万能的大熊”因造谣联想集团,被判向联想赔礼道歉,要在微博账号首页置顶位置发布致歉声明并连续保留30日&…

【访问者模式】设计模式系列:解锁复杂对象结构的秘密武器

文章目录 访问者模式详解:理论与实践1. 引言1.1 访问者模式的历史背景1.2 模式的动机与应用场景1.3 为什么选择访问者模式 2. 访问者模式概述2.1 定义2.2 问题场景2.3 模式结构 3. 模式优缺点分析3.1 优点3.2 缺点 4. 访问者模式实现步骤4.1 创建抽象元素接口4.2 实…

GitHub 与 AWS CodeCommit

代码库对决 欢迎来到雲闪世界。在软件开发领域,高效管理代码至关重要。Git 存储库等版本控制系统 (VCS) 是无名英雄,为代码更改、协作和历史跟踪提供了安全避风港。在选择合适的存储库平台时,出现了两个巨头:GitHub 和 AWS CodeC…

【前端面试】看react源码,解读useState

点击:react git 链接 截止2024.8.22最新版本如下 React hooks 源码好深,hook封装位于packages/react-reconciler/src/ReactFiberHooks.js hook的数据类型: export type Hook = {memoizedState: any,baseState: any,baseQueue: Update<any, any> | null,queue: an…

Vue vue/cli3 与 vue/cli4 v-for 和 v-if 一起使用冲突

问题描述 异常信息&#xff1a;[vue/no-use-v-if-with-v-for] The this.$router.options.routers expression inside v-for directive should be replaced with a computed property that returns filtered array instead. You should not mix v-for with v-if.eslint-plugin-v…