基础11:深浅拷贝

2023-11-07

1. 浅拷贝

创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

简单来说:浅拷贝只拷贝了对象第一层属性的基本类型值,以及第一层的引用地址。

常见的浅拷贝场景:
  • Object.assign()
let a = {
    name: "book",
    book: {
        price: "45"
    }
}
let b = Object.assign({}, a);
a.name = "change";
a.book.price = "55";
console.log(a);  // {name: "change", book: { price: 55 }}
console.log(b);  // {name: "book", book: { price: 55 }}
  • 展开语法 Spread

    let a = {
        name: "book",
        book: {
            price: "45"
        }
    }
    let b = {...a}
    a.name = "change";
    a.book.price = "55";
    console.log(a);  // {name: "change", book: { price: 55 }}
    console.log(b);  // {name: "book", book: { price: 55 }}
    
  • Array.prototype.slice()

    let a = [0, "1", [2, 3]];
    let b = a.slice(1);
    console.log(b);
    // ["1", [2, 3]]
    
    a[1] = "99";
    a[2][0] = 4;
    console.log(a);
    // [0, "99", [4, 3]]
    
    console.log(b);
    //  ["1", [4, 3]]
    

2. 深拷贝

深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。

常见的深拷贝场景:
  • JSON.parse(JSON.stringify(object))

    虽然这种方法,做深拷贝的时候比较简单,但是会有以下几个问题:

    1、会忽略 undefined

    2、会忽略 symbol

    3、不能序列化函数

    4、不能解决循环引用的对象

    5、不能正确处理new Date()

    6、不能处理正则

    • undefinedsymbol 和函数这三种情况,会直接忽略。(因为这三种值不是有效的JSON值,在JSON.stringify的时候会被忽略)。

      let obj = {
          name: 'book',
          a: undefined,
          b: Symbol('muyiy'),
          c: function() {}
      }
      console.log(obj);
      // {
      // 	name: "muyiy", 
      // 	a: undefined, 
      //  b: Symbol(muyiy), 
      //  c: ƒ ()
      // }
      
      let b = JSON.parse(JSON.stringify(obj));
      console.log(b);
      // {name: "book"}
      
    • 循环引用情况下,会报错。

      let obj = {
          a: 1,
          b: {
              c: 2,
         		d: 3
          }
      }
      obj.a = obj.b;
      obj.b.c = obj.a;
      
      let b = JSON.parse(JSON.stringify(obj));
      // Uncaught TypeError: Converting circular structure to JSON
      
    • new Date 情况下,转换结果不正确。

      new Date();
      // Mon Dec 24 2018 10:59:14 GMT+0800 (China Standard Time)
      
      JSON.stringify(new Date());
      // ""2018-12-24T02:59:25.776Z""
      
      JSON.parse(JSON.stringify(new Date()));
      // "2018-12-24T02:59:41.523Z"
      
    • 正则情况下,

      let obj = {
          name: "muyiy",
          a: /'123'/
      }
      console.log(obj);
      // {name: "muyiy", a: /'123'/}
      
      let b = JSON.parse(JSON.stringify(obj));
      console.log(b);
      // {name: "muyiy", a: {}}
      
  • jQuery.extend() 和 lodash.cloneDeep()

3. 总结

和原数据是否指向同一对象 第一层数据为基本数据类型 原数据中包含子对象
赋值 改变会使原数据一同改变 改变会使原数据一同改变
浅拷贝 改变会使原数据一同改变 改变会使原数据一同改变
深拷贝 改变会使原数据一同改变 改变会使原数据一同改变
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基础11:深浅拷贝 的相关文章

随机推荐

  • # Vue 配置前端后端路由地址

    Vue 配置前端后端路由地址 文章目录 Vue 配置前端后端路由地址 前端路由配置 配置项目地址 配置页面路由 路径跳转 后端路由配置 配后端请求地址 前端路由配置 配置项目地址 修改 config index js的配置文件 proxyT
  • jvm监控工具之jvisualvm&jmc

    一 jvisualvm 监控 方法一 使用 jstatd 1 创建策略文件 jstatd all policy 内容如下 grant codebase file java home lib tools jar permission java
  • 许奔创新社-第7问:构建创意的液态网络需要哪些条件?

    在 创意诞生的关键要素 中 我们曾提到一个非常重要的问题 对于体量差异不大的液态网络 为什么有的能产出大量高价值的创意 而剩下的却如一潭死水般无法产出分毫创意 造成此等差距的原因究竟是什么 液态网络这个词 是由创新者史蒂文 约翰逊 Stev
  • iptables 命令

    NAME iptables administration tool for IPv4 packet filtering and NAT SYNOPSIS iptables ADC 指定链的规则 A 添加 D 删除 C 修改 iptables
  • 【Neo4j】第 4 章:图形数据科学Library and Path Finding

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • Java RMI 入门

    Java RMI 入门 如何通信 实战 完整代码 Java RMI 指 JDK 内置的关于实现远程方法调用 Remote Method Invocation 的 API 这些 API 位于包 java rmi 中 通过 Java RMI 可
  • java事件监听机制(观察者设计模式的实际运用)

    package cn yang test controller java的事件监听机制和观察者设计模式 Created by Dev yang on 2016 3 1 public class Demo public static void
  • QT-MQTT客户端和服务端介绍

    MQTT Message Queuing Telemetry Transport 是一种基于发布 订阅模式的消息传递协议 在QT中使用MQTT 可以轻松地创建MQTT客户端和服务端 并实现设备之间的通信 在QT中 可以使用Qt MQTT模块
  • 7个Python有趣的lambda应用

    7个Python有趣的lambda应用 1 排序sort 2 寻找最大值max 3 查找最小值min 4 filter 5 map 6 reduce 7 Sorted 源码 1 排序sort 2 寻找最大值max 3 查找最小值min 4
  • javascript数据验证

    校验是否全由数字组成 function isDigit s var patrn 0 9 1 20 if patrn exec s return false return true 校验登录名 只能输入5 20个以字母开头 可带数字 的字串
  • 2021美赛E题

    2021年 问题E 重新优化食物系统 最近的事件向我们表明 我们的全球粮食系统即使在世界的某些地区也是不稳定的 它通常服务于全世界 这些不稳定的部分原因是我们目前的全球气候变化 庞大的国内和国际食品生产商和经销商体系 这个食物系统 使食物的
  • 2022-15-Java 设计模式-抽象工厂模式

    在工厂方法模式中 我们使用一个工厂创建一个产品 一个具体工厂对应一个具体产品 但有时候我们需要一个工厂能够提供多个产品对象 而不是单一的对象 这个时候我们就需要使用抽象工厂模式 在介绍抽象工厂模式前 我们先厘清两个概念 产品等级结构 产品等
  • 【Java书笔记】:《Redis 深度历险:核心原理和应用实践》分布式锁,延时队列,位图,HyperLogLog,布隆过滤器,漏斗限流,GeoHash,Scan,管道,事务,主从,Redis源码

    Redis 深度历险 核心原理和应用实践 目 录 开篇 授人以鱼不若授人以渔 Redis 可以用来做什么 7 由 Redis 面试想到的 7 小册的内容范围 8 Redis 可以做什么 8 基础 万丈高楼平地起 Redis 基础数据结构 1
  • 备战数学建模34-BP神经网络预测2

    目录 一 辛烷值的预测 1 题目分析与原理介绍 2 神经网络建立过程 3 预测结果分析 BP神经网络模型 包含输入层 隐含层和输出层 正向传播过程是通过输入样本到输入层 通过输入层经过各层隐藏层 最后到达输出层 若输出层输出值与期望值的输出
  • STM32学习----通用定时器的应用(输入捕获,测量周期和占空比)

    输入捕获的应用 输入捕获一般是用来测量输入信号的频率 占空比这些信息 输入捕获的原理 捕获的原理 1 信号从某个通道输入 比如通道1 CH1 2 经过滤波和边沿检测后产生两个一模一样的信号TI1FP1和TI1FP2 TI1FP1送给捕获通道
  • 身份证二进制数据解析

    头数据 AA AA AA 96 69 05 08 00 00 90 01 00 04 00 文本信息 256个字节 使用Unicode解码 得到中文信息 姓名 30个字节 性别 2个字节 民族 4个字节 出生日期 16个字节 地址 70个字
  • 数据治理项目工作方式总结

    1 当工作完成后 每天完成对应的计划任务列表分析 图表展示 代码展示等汇总报告 PPT 是简单的方式 word excel也是可以的 这边习惯用word 写一写文档之类的 excel 做工作拆分和总结 PPT 做工作汇报 2 没有的话 可以
  • 入门数据结构,c语言实现循环队列实现(详细篇)。

    目录 一 前言 二 循环队列的概念 三 实现循环队列 1 头文件与特殊函数介绍 2 循环队列的结构体 3 队列的初始化 4 判断队列是否为空 5 队列的进队操作 6 队列的出队操作 7 返回队头 8 返回队列长度 9 放回队列容量大小 10
  • MIB文件解析,常见报错整理

    我用的是这个工具FmMib 需要的可以给我留言 目前网上关于类似的报错整理还是挺少的 可能这个知识点用的也不多 我开始解析mib文件时 小问题还是挺多的 很多书写问题 格式都是自己手动改源文件才可以解析出来 建议在做类似解析的时候可以先学习
  • 基础11:深浅拷贝

    1 浅拷贝 创建一个新对象 这个对象有着原始对象属性值的一份精确拷贝 如果属性是基本类型 拷贝的就是基本类型的值 如果属性是引用类型 拷贝的就是内存地址 所以如果其中一个对象改变了这个地址 就会影响到另一个对象 简单来说 浅拷贝只拷贝了对象