回顾一下,我们对传参的讨论,对象的传参是引用传递,我们传递的是对象数据所在的内存地址;

那么无论我们怎么去赋值,所有变量指向的都是同一块内存;

如上图所示,无论我去使用哪个变量去操作对象的属性,改变的始终是同一块内存区域的数据;

现在,我希望可以将obj1的内存数据,完整复制一份,存放到另一个内存区域obj2,使得这两块内存,保存的数据内容完全一样,但是我改变其中一块内存的数据,都不会影响到另一块内存的数据;

想一想,我们应该怎么做,才能达到这一目的?

浅拷贝

能想到的,是遍历对象的属性(基本数据类型),然后依次赋值给另一个对象的属性,因为说到复制,就是指值传递,只有基本数据类型是值传递:

如上图所示,我们遍历了obj1的属性,并赋值给了obj2,我们修改了obj2的name1属性,但是并没有改变obj1的name1属性,证明我们成功复制了一份obj1的内存数据;

那我们每次都需要用for-in循环吗?JS有没有自带一些方法来实现浅拷贝呢?

有的:

  • Object.assign()方法

    语法为Object.assign(dest, src1, src2,,,,,)

    第一个变量dest是目标对象,即将后面的对象的属性值复制给目标对象;

    后面的所有变量src即是源对象,会将所有源对象的属性值全复制给目标对象,如果有属性名同名,则会进行覆盖;

    调用该方法,结果会返回dest;

深拷贝

现在假设,obj1中,name1是一个对象类型,上面的拷贝方式,还行得通吗?

看上图,obj2对name1的name属性修改为了Bob,而obj1的name1的name属性,输出结果也为Bob,这意味着,obj1和obj2的name1属性指向的是同一块内存区域;

这是因为,对象是引用传递,我们在调用Object.assign()方法时,只是将obj1的name1的内存地址,复制给了obj2的name1,此时他们之间的内存关系,如下所示:

也就是说,此时obj1和obj2并不完全互相独立,他们之间还共同管理着name1这块内存;

这种不完全互相独立的拷贝,我们称之为浅拷贝

所以,完全互相独立的拷贝,我们就称之为深拷贝

那么,我们怎样才能实现深拷贝,使两者完全互相独立呢?

可行的方法是,对name1这个对象,再进行一次浅拷贝。

这样太麻烦了,JS有没有自带的深拷贝的方法呢?

JavaScript:对象:如何复制一个对象?浅拷贝与深拷贝的更多相关文章

  1. Python中的赋值(复制)、浅拷贝、深拷贝之间的区别

    1.赋值: 只是复制了新对象的引用,不会开辟新的内存空间.  2.浅拷贝: 创建新对象,其内容是原对象的引用.    浅拷贝有三种形式:切片操作,工厂函数,copy模块中的copy函数.    如: ...

  2. java List复制:浅拷贝与深拷贝

    Java的拷贝可以分为三种:浅拷贝(Shallow Copy).深拷贝(Deep Copy).延迟拷贝(Lazy Copy). 在java中除了基本数据类型之外(int,long,short等),还存 ...

  3. JavaScript对象深复制

    1.原理 使用JSON,当然需要JSON安全的格式,JSON安全请参考:http://www.cnblogs.com/mengfangui/p/8257269.html 2.示例 <!DOCTY ...

  4. List的复制 (浅拷贝与深拷贝)

    开门见山的说,List的复制其实是很常见的,List其本质就是数组,而其存储的形式是地址 如图所示,将List A列表复制时,其实相当于A的内容复制给了B,java中相同内容的数组指向同一地址,即进行 ...

  5. Java小知识----List复制:浅拷贝与深拷贝

    原文地址: https://blog.csdn.net/demonliuhui/article/details/54572908 List浅拷贝 众所周知,list本质上是数组,而数组的是以地址的形式 ...

  6. Python的复制,浅拷贝和深拷贝

    https://www.cnblogs.com/xueli/p/4952063.html 如果给一个变量赋值一个对象,那么新变量和原对象变量将会是同一个引用,其中一方改变,另一方也会改变. 该问题可以 ...

  7. JavaScript对象浅复制

    1.概述 Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target). 注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面 ...

  8. javascript 对象的复制

    1. jQuery has a method that can be used to deep-clone objects, the$.extend() function. Let’s take a ...

  9. JavaScript对象复制(一)(转载)

    在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针.引用.地址之类的,所以直接用"="就可以把一个对象复制给另外一 ...

  10. Java对象的复制

      Java中对象的赋值分为浅拷贝和深拷贝 1.对象浅拷贝 public class CloneTest{ static class Emp{ String name; int age; Date h ...

随机推荐

  1. MES系统与ERP系统信息集成有哪些原则?

    首先,MES和ERP应该是两个独立的系统,简单的说,ERP与MES有点像公司总部与分厂的关系,ERP向MES发指令,MES向ERP做汇报,所以可以按照这个思维来考虑或类比来处理.从企业的管理来说,ER ...

  2. Allure的简单使用

    Allure的简单使用 1.Allure简介 简单的理解下,可以把Allure当成一个用于生成美观测试报告的开源工具,配合Pytest测试框架使用更佳. 也就是说,Allure是在Pytest执行测试 ...

  3. C++ 标准文档

    正式的 C++ 标准文档不是免费的,需要付费购买,可以到 ISO Store 或者其成员国的标准商店购买正版(中国 SACinfo 标准信息服务网,美国 ANSI WebStore,其他成员国可查看 ...

  4. 基于QT和C++实现的翻金币游戏

    基于QT和C++的翻金币游戏 声明: QT翻金币项目可以说是每个新学QT的同学都会去写的一个项目,网上的源码也很多,我也是最近刚开始学QT,所以也参考了很多前辈的代码自己重新敲了一遍代码. 游戏介绍: ...

  5. mybatis-plugin插件执行原理

    mybatis-plugin插件执行原理 今天主要是在看mybatis的主流程源码,其中比较感兴趣的是mybatis的plugin功能,这里主要记录下mybatis-plugin的插件功能原理. pl ...

  6. Pipeline流水线设计的最佳实践

    谈到到DevOps,持续交付流水线是绕不开的一个话题,相对于其他实践,通过流水线来实现快速高质量的交付价值是相对能快速见效的,特别对于开发测试人员,能够获得实实在在的收益.很多文章介绍流水线,不管是j ...

  7. 浅谈ORM-对象关系映射

    目前.NET(C#)中比较流行的ORM框架: SqlSugar (国内) Dos.ORM (国内) Chloe (国内) StackExchange/Dapper (国外) Entity Framew ...

  8. 2022HNCTF--WEB

    @ 目录 [Week1]Interesting_http 分析 payload [Week1]2048 分析 payload [Week1]easy_html 分析 paylaod [Week1]In ...

  9. [CS61A] Lecture 5&6&7. Environments & Design & Functions Examples & Homework 2: Higher Order Functions

    [CS61A] Lecture 5&6&7. Environments & Design & Functions Examples & Homework 2: ...

  10. 阿里云 ACK 接入观测云

    简介 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理.2021 年成为国内唯一连续三年入选 Gartner 公共云容器报告的 ...