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

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

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

现在,我希望可以将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. 如何生成均匀随机数 C++

    #include <iostream> #include <fstream> #include <cstdlib> #include <ctime> u ...

  2. C++面向对象编程之虚指针、虚表

    1.当编译器看到一个函数调用,有2个考量:静态绑定or动态绑定 静态绑定是"call xxx",xxx 是表示地址,call 是汇编语言的一个动作,它一定会调用到某个地址: 当符合 ...

  3. springmvc 上传文件时的错误

    使用springmvc上传文件一直失败,文件参数一直为null, 原来是配置文件没写成功. <bean id="multipartResolver" class=" ...

  4. SSM(Spring,SpringMVC,Mybatis)框架整合项目

    快速上手SSM(Spring,SpringMVC,Mybatis)框架整合项目 环境要求: IDEA MySQL 8.0.25 Tomcat 9 Maven 3.6 数据库环境: 创建一个存放书籍数据 ...

  5. Linux 下搭建 HBase 环境

    Linux 下搭建 HBase 环境 作者:Grey 原文地址: 博客园:Linux 下搭建 HBase 环境 CSDN:Linux 下搭建 HBase 环境 前置工作 首先,需要先完成 Linux ...

  6. Tomcat 调优之从 Linux 内核源码层面看 Tcp backlog

    前两天看到一群里在讨论 Tomcat 参数调优,看到不止一个人说通过 accept-count 来配置线程池大小,我笑了笑,看来其实很多人并不太了解我们用的最多的 WebServer Tomcat,这 ...

  7. uoj349【WC2018】即时战略

    题目链接 WC出了点意外滚粗了,来补补题. \(O(n^2)\)的时间复杂度,\(O(nlogn)\)的询问次数应该还是比较好想的,每次要打通到x的路径,对当前已知的树不断的找重心并询问在重心的哪颗子 ...

  8. C# 7.0 添加和增强的功能【基础篇】

    C# 7.0 版是与 Visual Studio 2017 一起发布. 虽然该版本继承和发展了C# 6.0,但不包含编译器即服务. 一.out 变量 以前我们使用out变量必须在使用前进行声明,C# ...

  9. SpringBoot 常用注解的原理和使用

    @AutoConfiguration 读取所有jar包下的 /META-INF/spring.factories 并追加到一个 LinkedMultiValueMap 中.每一个url中记录的文件路径 ...

  10. 部署redis集群

    1.redis部署 redis单实例部署参考:https://www.cnblogs.com/silgen/p/16537299.html 版本:6.2.7 集群:6个节点(redis集群至少3个节点 ...