【学习笔记66】JavaScript的深浅拷贝

news2024/10/5 20:18:28

一、赋值

  •  只要是引用数据类型, 那么在赋值的时候, 就是引用地址的传递
        // 赋值:字符串
        const s1 = '123';
        let s2 = s1;     // 赋值
        console.log(s2 === s1);  // true
        s2 = '456';
        console.log(s1); // 123
        console.log(s2); // 456

        let o1 = { a: 1 };
        let o2 = o1;          // 赋值
        console.log(o2 == o1);
        o2.a = 999;
        console.log(o1);
        console.log(o2);

        let a1 = [1, 2, 3];
        let a2 = a1;       // 赋值
        console.log(a2 == a1);
        a2[0] = 999;
        console.log(a1);
        console.log(a2);

二、浅拷贝

  •  遍历对象拿到对象的每一个keyvalue,然后赋值给另外一个对象
  •  如果所有的value都是基本数据类型, 那么浅拷贝完成之后, 修改新对象不会影响到老对象
  • 如果 value 有引用数据类型(出现了多层数据结构), 那么浅拷贝只能拷走第一层数据结构, 多层的没有办法处理
  • 注意:深浅拷贝一定是引用数据类型对象, 数组, 函数(基本只有对象和数组)

1、浅拷贝的实现

        let o1 = {
            a: 1,
            b: 2,
            c: 3,
            d: {
                d1: '001',
                d2: '002',
                d3: '003'
            }
        }
        let o2 = {}
        for (let key in o1) {
            // 遍历o1对象所有的key, 然后赋值给对象o2
            // console.log(key, o1[key]);
            o2[key] = o1[key];
        }
        console.log(o1); // {a: 1, b: 2, c: 3}
        console.log(o2); // {a: 1, b: 2, c: 3}
        console.log(o1 === o2); // false

        let o1 = {
            a: 1,
            b: 2,
            c: 3,
            d: {
                d1: '001',
                d2: '002',
                d3: '003'
            }
        }
        let o2 = {}
        for (let key in o1) {
            // 遍历o1对象所有的key, 然后赋值给对象o2
            // console.log(key, o1[key]);
            o2[key] = o1[key];
        }

        o2.b = 999;
        console.log(o1 === o2); // false
        console.log(o1); // {a: 1, b: 2, c: 3}
        console.log(o2); // {a: 1, b: 999, c: 3}

        let o1 = {
            a: 1,
            b: 2,
            c: 3,
            d: {
                d1: '001',
                d2: '002',
                d3: '003'
            }
        }
        let o2 = {}
        for (let key in o1) {
            // 遍历o1对象所有的key, 然后赋值给对象o2
            // console.log(key, o1[key]);
            o2[key] = o1[key];
        }

        o2.d.d1 = 'QF666'
        console.log(o1 === o2); 
        console.log(o1); 
        console.log(o2); 

 2、JS提供的浅拷贝

  • Object.assign(新对象, 原始对象)
  • 将原始对象中所有的key,全部浅拷贝到新对象中, 然后返回一个对象
        let o1 = {
            a: 1,
            b: 2,
            c: 3,
            d: {
                d1: '001',
                d2: '002',
                d3: '003'
            }
        }
        let o2 = Object.assign({}, o1);
        console.log(o1);
        console.log(o2);

三、深拷贝

  • 不管数据有多少层数据结构, 百分百复制出来一份,一摸一样但是毫不相关的数据
        let o1 = {
            a: 1,
            b: 2,
            c: 3,
            d: {
                d1: '001',
                d2: '002',
                d3: '003'
            }
        }
        let o2 = {}
        function deepClone(target, origin) {
            // 将origin完全百分百的复制出来一份, 到target中
            for (let k in origin) {
                // console.log(k, origin[k])
                if (origin[k].constructor === Object) {
                    target[k] = {}
                    deepClone(target[k], origin[k])
                } else if (origin[k].constructor === Array) {
                    target[k] = []
                    deepClone(target[k], origin[k])
                } else {
                    target[k] = origin[k]
                }
            }
        }

        deepClone(o2, o1);
        console.log(o1  === o2);
        console.log(o1);
        console.log(o2);

        let o1 = {
            a: 1,
            b: 2,
            c: 3,
            d: {
                d1: '001',
                d2: '002',
                d3: '003'
            }
        }
        let o2 = {}
        function deepClone(target, origin) {
            // 将origin完全百分百的复制出来一份, 到target中
            for (let k in origin) {
                // console.log(k, origin[k])
                if (origin[k].constructor === Object) {
                    target[k] = {}
                    deepClone(target[k], origin[k])
                } else if (origin[k].constructor === Array) {
                    target[k] = []
                    deepClone(target[k], origin[k])
                } else {
                    target[k] = origin[k]
                }
            }
        }
        deepClone(o2, o1);

        o2.d.d2 = 'QF666';
        console.log(o2);
        console.log(o1);

2、JS中提供的方法

        let o1 = {
            a: 1,
            b: 2,
            c: 3,
            d: {
                d1: '001',
                d2: '002',
                d3: '003'
            }
        }

        let o2 = JSON.parse(JSON.stringify(o1));
        o2.d.d3 = '9999999';
        console.log(o1);
        console.log(o2);

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

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

相关文章

【iOS】—— GET和POST以及AFNetworking框架

GET和POST以及AFNetworking框架 文章目录GET和POST以及AFNetworking框架GET和POSTGET和POST区别GETGET请求步骤GET请求代码POSTPOST请求步骤POST请求代码AFNetworking简介添加头文件GETGET方法GET方法参数GET方法代码样例POSTPOST方法第一种:第二种:先来…

[附源码]计算机毕业设计springboot防疫物资捐赠

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

springboot+jsp学生成绩查询考务系统

众所周知,现代信息技术是现代教育技术的基础和核心,培养和创新型的人才,必须依靠现代教育技术。从这一层意义上讲,我们说掌握一定的计算机应用技能已经成为国家未来的合格建设者的必备素质,所以现在在大学中对非计算机…

Huggingface的介绍,使用(CSDN最强Huggingface入门手册)

Huggingface的介绍,使用(CSDN最强Huggingface入门手册)返回论文和资料目录 1.Huggingface的简介 Huggingface即是网站名也是其公司名,随着transformer浪潮,Huggingface逐步收纳了众多最前沿的模型和数据集等有趣的工…

代码源每日一题div1 DP 数组划分

数组划分 - 题目 - Daimayuan Online Judge 题意: 思路: 关于位运算的最大值,只需要按位去贪心即可,即从高位向低位贪心,答案一定是1111000的形式 那么我们去枚举这个1和0的分界线在哪就好了 对于一个确定好的分界…

模板学堂丨DataEase用户操作日志分析大屏

DataEase开源数据可视化分析平台于2022年6月正式发布模板市场(https://dataease.io/templates/)。模板市场旨在为DataEase用户提供专业、美观、拿来即用的仪表板模板,方便用户根据自身的业务需求和使用场景选择对应的仪表板模板,并…

基于FPGA的ALU计算器verilog实现

欢迎订阅《FPGA学习入门100例教程》、《MATLAB学习入门100例教程》 目录 一、理论基础 二、核心程序 三、测试结果 一、理论基础 Verilog HDL是一种硬件描述语言,以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式…

粒子群算法查找函数最小值

实现 函数 F01、F06 的优化测试 以下内容是现有算法的运行结果、调参分析、及代码实现,用于给其他人提供参考,懒得改了hh 1. 运行结果 参数 w 0.5 (可更改) c1 2.0 (可更改) c2 2.0 (可更改&…

2.每天进步一点点-Python爬虫需要了解一下基础的web相关内容

14天学习训练营导师课程: 杨鑫《Python 自学编程基础》 杨鑫《 Python 网络爬虫基础》 杨鑫《 Scrapy 爬虫框架实战和项目管理》 文章目录1.网络请求过程1.1通过 URL 查找服务器 IP1.2三次握手建立 TCP 连接1.3发送 HTTP 请求1.4服务器响应请求1.5浏览器解析 HTML1.…

21年-自研-笔试题

目录背景题目1、Object的常用方法2、 和 equals 的区别是什么?equals3、以下代码的运行结果4、以下代码的运行结果5、String, StringBuilder,StringBuffer6、ArrayList和LinkedList7、一些常用的线程安全的集合类8、以下代码的运行结果9、完成下面的代码…

Java环境准备——JDK下载和安装、IDEA下载和安装

一、JDK下载及安装 1、必要性:JDK是整个Java开发的核心。 2、下载网址:Java Downloads | Oracle 3、选择下载JDK17的原因:JDK17 是Java的长期支持版本。 4、下载到本地后,双击进行安装,然后点击下一步,安…

AI物品分类识别管理系统uniapp源码带文档教程

技术架构 技术框架:SpringBoot2 Mysql5.7 Mybatis-Plus uniapp Swagger2 RuoYi-fast swagger-bootstrap-ui 运行环境:jdk8 IntelliJ IDEA maven 宝塔面板 百度智能云平台服务 本地api接口端搭建教程 后端需要准备相关的IDE和JDK8开发环境 , 前…

GIT技巧

目录 基础命令 commit 、branch merge rebase 高级特性 自由修改提交树 cherry-pick rebase 远程仓库命令 基础命令 commit 、branch Git Commit Git 仓库中的提交记录保存的是你的目录下所有文件的快照,就像是把整个目录复制,然后再粘贴一样…

Linux内核中ideapad-laptop.c文件全解析6

接前一篇文章《Linux内核中ideapad-laptop.c文件全解析5》,地址为: Linux内核中ideapad-laptop.c文件全解析5_蓝天居士的博客-CSDN博客 上一篇详细分析了ideapad_debugfs_init,本篇详细分析ideapad_input_init。 ideapad_input_init ideap…

Word控件Spire.Doc 【图像形状】教程(7): 如何使用 C# 在 Word 中替换图像

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下,轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具,专注于创建、编辑、转…

b站黑马JavaScript的Ajax案例代码——聊天机器人案例

目录 目标效果: 更换的新接口: 1.机器人智能回复接口:http://www.liulongbin.top:3006/api/robot 2.机器人语音接口:http://www.liulongbin.top:3006/api/synthesize 重点原理: 1.jQuery中trim方法 2.jquery中a…

Hive数据查询语言-DQL-含示例演练(Select查询数据、Join查询)

文章目录1. Select查询数据1.1 基础语法1.1.1 select_ecpr1.1.2 ALL、DISTINCT1.1.3 WHERE1.1.4 分区查询、分区裁剪1.1.5 GROUP BY1.1.6 HAVING1.1.7 LIMIT1.1.8 执行顺序1.2 高阶语法1.2.1 ORDER BY1.2.2 CLUSTER BY1.2.4 Union联合查询1.2.5 from子查询(Subqueri…

Allegro自动沿着目标任意形状走线操作指导

Allegro自动沿着目标任意形状走线操作指导 Allegro有个非常好用的功能,支持自动沿着目标任意形状走线,对于异形板框走线尤其方便,以下图为例,需要沿着这个外形走一段线 具体操作如下 点击add connect命令 点击空白处 鼠标右击选择contour命令 出现一个对话框,当前是…

03【Spring AOP、CGBLIB代理】

文章目录03【Spring AOP、CGBLIB代理】一、AOP前奏1.1 案例1.1.1 需求设计1.1.2 需求修改1.1.3 需求增加1.1.4 分析存在的问题1.2 动态代理1.2.1 定义接口:1.2.2 日志代理类1.2.3 缓存代理类:1.2.4 测试类二、AOP2.1 AOP 概述2.1.1 纵向编程2.1.2 纵横配…

【Java进阶篇】第六章 IO流

文章目录一、IO流的概述1、流2、流的分类3、Java IO流的四大块4、流的两大特性5、java.io包下的16个常用流二、文件专属流1、java.io.FileInputStream2、java.io.FileOutputStream3、java.io.FileReader4、java.io.FileWriter三、缓冲流与转换流1、java.io.BufferedReader2、ja…