对浅拷贝的理解

问题背景

我之前一直以为浅拷贝出来的新对象和旧对象的引用地址是相同的,但是通过Object和===发现浅拷贝的新对象和旧对象的引用地址不同!!

   const obj1 = { name: "Alice", test: { age: 12 } };
    const obj4 = Object.assign({}, obj1); // 浅拷贝
    obj4.name = "hhh";
    obj4.test.age = 99;
    console.log("obj1", obj1);
    console.log("obj4", obj4);

    const obj2 = { name: "Alice" };
    const obj3 = obj1;

    console.log(Object.is(obj1, obj2)); // false,因为它们的引用地址不同
    console.log(Object.is(obj1, obj3)); // true,因为它们指向同一个对象
    console.log(Object.is(obj1, obj4)); // false!!!
    console.log(obj1 === obj2); // false
    console.log(obj1 === obj3); // true
    console.log(obj1 === obj4); // false!!!

甚至当对象不止一层的时候,也是引用对象不同
因为我一直以为不止一层,那么浅拷贝就直接拷贝地址,那么引用地址总应该相同了吧,唉

   const obj5 = {test: { age: 12 } };
    const obj6 = Object.assign({}, obj5); // 浅拷贝
    console.log(Object.is(obj5, obj6)); // false!!!
    console.log(obj5 === obj6); // false!!!

还是有疑问

既然浅拷贝出来的对象引用地址不同,为什么obj1.test.age也修改了

const obj1 = { name: "Alice", test: { age: 12 } };
    const obj4 = Object.assign({}, obj1);
    obj4.name = "hhh";
    obj4.test.age = 99;
    console.log("obj1", obj1);
    console.log("obj4", obj4);

这是因为浅拷贝只会复制对象的第一层属性,而不会递归复制对象中嵌套的对象。所以虽然 obj1 和 obj4 是两个不同的对象,但它们的 test 属性引用的是同一个对象

   console.log(Object.is(obj1.test, obj4.test)); // true!!!
    console.log(obj1.test === obj4.test); // true!!!

修改 obj4.test.age 实际上修改了 test 属性指向的对象,因此 obj1 中的 test 属性也会受到影响。

要解决这个问题,你需要使用深拷贝而不是浅拷贝。深拷贝会递归地复制对象及其所有嵌套的对象,确保所有对象都是独立的,没有共享引用。

在插一句

    const obj7 = { name: "Alice" };
    const obj8 = Object.assign({}, obj7); // 浅拷贝
    console.log(Object.is(obj7.name, obj8.name)); // true
    console.log(obj7.name === obj8.name); // true

在这段代码中,obj7 和 obj8 中的 name 属性都是字符串,它们的值是相同的,因此 Object.is(obj7.name, obj8.name) 和 obj7.name === obj8.name 都会返回 true。

需要注意的是,这里的比较并不是比较两个对象的引用地址,而是比较它们的值。在 JavaScript 中,字符串是基本数据类型,比较时会直接比较它们的值。
要判断两个字符串的引用是否相同,可以使用严格相等运算符(===)或 Object.is() 方法进行比较。这会比较字符串的引用地址是否完全相同。

const str1 = "hello";
const str2 = "hello";
const str3 = new String("hello");

console.log(str1 === str2); // true,直接量相同
console.log(str1 === str3); // false,str3 是一个对象,与 str1 的引用不同
console.log(Object.is(str1, str2)); // true
console.log(Object.is(str1, str3)); // false

在这个例子中,str1str2 是直接量,它们的引用地址相同,因此严格相等运算符和 Object.is() 方法都会返回 true。而 str3 是通过构造函数 String 创建的字符串对象,与直接量的引用地址不同,因此比较结果为 false

总结

浅拷贝出来的对象和旧对象的引用地址是不同的。在浅拷贝过程中,会创建一个新的对象,该对象包含了源对象的所有可枚举属性的副本。因此,尽管浅拷贝后的对象可能与源对象具有相同的属性值,但它们是两个不同的对象,存储在内存中的不同位置,拥有不同的引用地址。

在这里插入图片描述

引用别人的文章:

http://t.csdnimg.cn/zSoTn


let arrayA = [1, '这是一个字符串', undefined, null, { obj: '这是一个obj' }];
console.log('原始的arrayA', arrayA)//原始的arrayA [1, 2, 3, 4, 5, 6, 7]
let arrayB = Array.from(arrayA)//浅拷贝(注意,浅拷贝只会拷贝一层)
let arrayC = arrayA//应用arrayA的堆地址

arrayA[0] = 99
arrayA[1] = "修改一下这个字符串"
arrayA[2] = "修改一下这个undefind"
arrayA[3] = "修改一下这个null"
arrayA[4].obj = "修改一下这个obj"

console.log('arrayA', arrayA)//[99, '修改一下这个字符串', 修改一下这个undefind, 修改一下这个null, { obj: '修改一下这个obj' }];
//arrayB是由Array.form浅拷贝来的,
console.log('arrayB', arrayB)//[1, '这是一个字符串', undefined, null, { obj: '修改一下这个obj' }]
//arrayC地址应用(arrayC是指向arrayA这个数组对象的堆内存的内存地址),所以arrayA改变后arrayC也会改变,因为它两指向的是同一个内存地址;
console.log('arrayC', arrayC)//[99, '修改一下这个字符串', 修改一下这个undefind, 修改一下这个null, { obj: '修改一下这个obj' }];

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux中 虚拟机 修改时间 centos7

方法1 :虚拟机内 设置 方法2 代码实现 timedatectl set-timezone "Asia/Shanghai"

iOS 17上如何恢复数据?iOS 17 数据恢复软件

“您好,我正在为我的 iPhone 寻找一款iOS 17 数据恢复软件。升级到 iOS 17 后,我丢失了 iPhone 上的所有照片、联系人和消息。有什么建议吗?” ——丹尼 iOS 17数据恢复软件下载 升级到iOS 17后如何恢复丢失的数据?由于在 iPhone…

Django中的事务

1 开启全局的事务 DATABASES {default: {ENGINE: django.db.backends.mysql, # 使用mysql数据库NAME: tracerbackend, # 要连接的数据库USER: root, # 链接数据库的用于名PASSWORD: 123456, # 链接数据库的用于名HOST: 192.168.1.200, # mysql服务监听的ipPORT: 3306, …

目标检测——小麦穗头数据集

一、重要性及意义 小麦穗头检测在农业领域具有重要意义,主要体现在以下几个方面: 首先,小麦穗头检测可以帮助农民和植物科学家准确评估作物的健康状况和成熟度。通过对小麦穗部的形态特征进行测量和分析,可以及时发现作物生长过…

应用在防蓝光显示器中的LED防蓝光灯珠

相比抗蓝光眼镜、防蓝光覆膜、软体降低蓝光强度这些“软”净蓝手段,通过对LED的发光磷粉进行LED背光进行技术革新,可实现硬件“净蓝”。其能够将90%以上的有害蓝光转换为450nm以上的长波低能光线,从硬件的角度解决了蓝光危害眼睛的问题&#…

python+django校园社交高校交友网站2x7r5.

本课题使用Python语言进行开发。代码层面的操作主要在PyCharm中进行,将系统所使用到的表以及数据存储到MySQL数据库中,方便对数据进行操作本课题基于WEB的开发平台,设计的基本思路是: 前端:vue.jselementui 框架&#…

【机器学习】深度神经网络(DNN):原理、应用与代码实践

深度神经网络(DNN):原理、应用与代码实践 一、深度神经网络(DNN)的基本原理二、DNN的优缺点分析三、DNN的代码实践四、总结与展望 在人工智能与机器学习的浪潮中,深度神经网络(Deep Neural Netw…

Spring Boot 集成 EasyExcel 3.x

Spring Boot 集成 EasyExcel 3.x Spring Boot 集成 EasyExcel 3.x 本章节将介绍 Spring Boot 集成 EasyExcel(优雅实现Excel导入导出)。 🤖 Spring Boot 2.x 实践案例(代码仓库) 介绍 EasyExcel 是一个基于 Java 的、…

【注解和反射】什么时候类会和不会被初始化?

继上一篇博客【注释和反射】类加载的过程-CSDN博客 目录 四、什么时候类会被初始化(主动引用)? 测试 五、什么情况下不会发生类的初始化(被动引用)? 测试 四、什么时候类会被初始化(主动引用…

<网络> HTTP

目录 前言: 一、再谈协议 (一)认识URL (二)Encode 和 Decode 二、HTTP 协议 (一)协议格式 (二)见一见请求 (三)见一见响应 三、模拟实现响…

模块化 DeFi L2 “Mode” 整合 Covalent Network(CQT),以获 Web3 最大数据集的支持

Covalent Network(CQT),作为 Web3 领先的数据层,宣布其统一 API 将与 Mode 集成,以加快其基于以太坊构建的专注于 DeFi 的模块化 Layer2 方案的数据访问速度。这一战略合作将通过为开发者提供更强大的工具和能力&#…

论文浅尝 | LoRA: 大模型的低秩适配

笔记整理:陈一林,东南大学硕士,研究方向为不确定知识图谱规则学习 链接:https://arxiv.org/abs/2106.09685 1、动机 自然语言处理的一个重要范式包括在通用领域数据上进行大规模预训练,然后对特定任务或领域进行适应性…

`THREE.AudioAnalyser` 音频分析

demo案例 THREE.AudioAnalyser 音频分析 入参 (Input Parameters): audio: 一个 THREE.Audio 实例,代表要分析的音频。fftSize: 快速傅里叶变换(FFT)的大小,用于确定分析的精度和频率分辨率。smoothingTimeConstant: 平滑时间…

[lesson58]类模板的概念和意义

类模板的概念和意义 类模板 一些类主要用于存储和组织数据元素 类中数据组织的方式和数据元素的具体类型无关 如:数组类、链表类、Stack类、Queue类等 C中将模板的思想应用于类,使得类的实现不关注数据元素的具体类型,而只关注类所需要实现的功能。 C中的类模板…

如何通过cURL库实现远程控制插座

如何通过cURL库实现远程控制插座呢? 本文描述了使用cURL库调用HTTP接口,实现控制插座,即插即用,先插入插座,再接电器,实现远程控制。 可选用产品:可根据实际场景需求,选择对应的规格…

开源文本嵌入模型M3E

进入正文前,先扯点题外话 这两天遇到一个棘手的问题,在用 docker pull 拉取镜像时,会报错: x509: certificate has expired or is not yet valid 具体是下面👇这样的 rootDS918:/volume2/docker/xiaoya# docker pul…

油猴脚本:bing 搜索结果居中

文章目录 效果预览脚本使用步骤安装油猴脚本添加脚本 效果预览 脚本 // UserScript // name bing居中 // namespace http://tampermonkey.net/ // version 2024-04-24 // description try to take over the world! // author You // match http…

牛客 题解

文章目录 day4_17**BC149** **简写单词**思路:模拟代码: dd爱框框思路:滑动窗口(同向双指针)代码: 除2!思路:模拟贪心堆代码: day4_17 BC149 简写单词 https://www.now…

缓存神器-JetCache

序言 今天和大家聊聊阿里的一款缓存神器 JetCache。 一、缓存在开发实践中的问题 1.1 缓存方案的可扩展性问题 谈及缓存,其实有许多方案可供选择。例如:Guava Cache、Caffine、Encache、Redis 等。 这些缓存技术都能满足我们的需求,但现…

CPDA|0到1突破:构建高效数据分析体系的秘密武器

在现今信息爆炸的时代,数据已经渗透到了我们生活的方方面面,成为了决策、创新和竞争优势的关键。因此,构建一套高效的数据分析体系,对于企业和个人而言,都是至关重要的。那么,如何在众多的数据海洋中脱颖而…