JavaScript:对象:如何复制一个对象?浅拷贝与深拷贝
回顾一下,我们对传参的讨论,对象的传参是引用传递,我们传递的是对象数据所在的内存地址;
那么无论我们怎么去赋值,所有变量指向的都是同一块内存;

如上图所示,无论我去使用哪个变量去操作对象的属性,改变的始终是同一块内存区域的数据;
现在,我希望可以将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:对象:如何复制一个对象?浅拷贝与深拷贝的更多相关文章
- Python中的赋值(复制)、浅拷贝、深拷贝之间的区别
1.赋值: 只是复制了新对象的引用,不会开辟新的内存空间. 2.浅拷贝: 创建新对象,其内容是原对象的引用. 浅拷贝有三种形式:切片操作,工厂函数,copy模块中的copy函数. 如: ...
- java List复制:浅拷贝与深拷贝
Java的拷贝可以分为三种:浅拷贝(Shallow Copy).深拷贝(Deep Copy).延迟拷贝(Lazy Copy). 在java中除了基本数据类型之外(int,long,short等),还存 ...
- JavaScript对象深复制
1.原理 使用JSON,当然需要JSON安全的格式,JSON安全请参考:http://www.cnblogs.com/mengfangui/p/8257269.html 2.示例 <!DOCTY ...
- List的复制 (浅拷贝与深拷贝)
开门见山的说,List的复制其实是很常见的,List其本质就是数组,而其存储的形式是地址 如图所示,将List A列表复制时,其实相当于A的内容复制给了B,java中相同内容的数组指向同一地址,即进行 ...
- Java小知识----List复制:浅拷贝与深拷贝
原文地址: https://blog.csdn.net/demonliuhui/article/details/54572908 List浅拷贝 众所周知,list本质上是数组,而数组的是以地址的形式 ...
- Python的复制,浅拷贝和深拷贝
https://www.cnblogs.com/xueli/p/4952063.html 如果给一个变量赋值一个对象,那么新变量和原对象变量将会是同一个引用,其中一方改变,另一方也会改变. 该问题可以 ...
- JavaScript对象浅复制
1.概述 Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target). 注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面 ...
- javascript 对象的复制
1. jQuery has a method that can be used to deep-clone objects, the$.extend() function. Let’s take a ...
- JavaScript对象复制(一)(转载)
在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针.引用.地址之类的,所以直接用"="就可以把一个对象复制给另外一 ...
- Java对象的复制
Java中对象的赋值分为浅拷贝和深拷贝 1.对象浅拷贝 public class CloneTest{ static class Emp{ String name; int age; Date h ...
随机推荐
- httpd常用配置之虚拟主机
httpd常用配置 目录 httpd常用配置 虚拟主机: 相同IP不同端口 不同IP相同端口 相同IP相同端口不同域名 切换使用MPM(编辑/etc/httpd/conf.modules.d/00-m ...
- 2022-08-08-esp32把玩记-①
layout: post cid: 4 title: esp32把玩记-① slug: 4 date: 2022/08/08 14:59:58 updated: 2022/08/08 14:59:58 ...
- Windows活动目录_初识
计算机组织形式 工作组(用户本地登录时构造SID进行权限分配): 域(统一身份验证与管理) 域注意事项 实体:域控.域用户.加入域的机子. 依赖的服务:netlogon服务 强制刷新组策略gpupda ...
- JavaScript基础&实战(5)js中的数组、forEach遍历、Date对象、Math、String对象
文章目录 1.工厂方法创建对象 1.1 代码块 1.2.测试结果 2.原型对象 2.1 代码 2.2 测试结果 3.toString 3.1 代码 3.2 测试结果 4.数组 4.1 代码 5.字面量 ...
- 基于YOLO和PSPNet的目标检测与语义分割系统(python)
基于YOLO和PSPNet的目标检测与语义分割系统 源代码地址 概述 这是我的本科毕业设计 它的主要功能是通过YOLOv5进行目标检测,并使用PSPNet进行语义分割. 本项目YOLOv5部分代码基于 ...
- C# String.Empty和""的区别
个人观点 Empty其实是string类中的一个静态的只读字段,因为是静态成员变量,所以String.Empty是在设计String类的时候就已经在内存上分配好了空间,故在使用Empty这个变量的时候 ...
- 题解 CF803A Maximal Binary Matrix
Luogu codeforces 前言 模拟赛原题.. 好好一道送分被我硬打成爆蛋.. \(\sf{Solution}\) 看了一波数据范围,感觉能 dfs 骗分. 骗成正解了. 大概就是将这个 \( ...
- 论文笔记 - Active Learning by Acquiring Contrastive Examples
Motivation 最常用来在 Active Learning 中作为样本检索的两个指标分别是: 基于不确定性(给模型上难度): 基于多样性(扩大模型的推理空间). 指标一可能会导致总是选到不提供有 ...
- 上下文管理器 context managet
定义:实现了上下文管理协议的对象,主要用于保存和恢复各种全局状态,关闭文件等,它本身就是一种装饰器. with语句 with语句就是为支持上下文管理器而存在的
- NET 6 实现滑动验证码(一)、创建工程
目录 实现滑动验证码的目的 创建.NET 6工程 实现滑动验证码的目的 传统验证码实现起来比较简单,但在OCR技术越来越成熟的情况下,验证码的破解难度越来越低,但如果将验证码难度加高(各种干扰背景,扭 ...