个人对赋值、浅拷贝和深拷贝的理解

简介: 个人对赋值、浅拷贝和深拷贝的理解

个人对赋值、浅拷贝和深拷贝的理解


术语

赋值

基本数据类型的赋值

对象数据类型的赋值

拷贝

浅拷贝

深拷贝


术语



基本数据类型:数字、字符串等这种。

对象数据类型:Object与Array这样的引用数据类型的。

赋值:可以看成等号连接,赋值的变量(等号左边)指向被赋值的变量(等号右边)


赋值



赋值看指向,觉得看字太累请直接理解代码。


基本数据类型的赋值



这里a的指向是一个1这个数字基本类型,

当b赋值2时等于是改变了b的指向,

b不指向a了,因此a不会改变

//这里a的指向是一个1这个数字基本类型
let a = 1;
//这里b赋值a指向a
let b = a;
//b不指向a了,指向2这个数字基本类型
b = 2;
console.log(a);//1
console.log(b);//2

对象数据类型的赋值


以下代码中,a赋值给b,对修改值与添加值,两个对象的内容完全一致

b和a指向同一个对象{},当b修改c添加d,但是没有对b直接进行赋值,因此

b还是指向a的,a内容也会同时改变

//a指向一个对象{ c: 1 }
let a = { c: 1 }
//b指向a
let b = a
console.log(a)//{ c: 1 }
console.log(b)//{ c: 1 }
//b修改指向的那个对象的内容
b.c = 2
b.d = 2
//由于b和a指向同一个对象{},因此b修改c添加d,a内容也会同时改变
console.log(a)//{ c: 2, d: 2 }
console.log(b)//{ c: 2, d: 2 }

拷贝



浅拷贝与深拷贝都是对赋值的不同用法。


浅拷贝



下面这段觉得写的花里胡哨可以先不看以后理解了再来看加深印象,我们可以跳过直接看代码和图。


浅拷贝只复制指向某个对象的指针,不复制对象本身。只拷贝对象空间,而不复制资源。新旧指针同时共享一块内存。所以当拷贝来的对象修改的是非对象的基本数据类型,由于是改变了对象本身而不是改变了复制来的指针指向的对象的内容,所以原对象不会改变,如果修改的是对象数据类型,则会改变原对象里的内容。常见实现方式:Object.assign()

let a = { c: 1, z: { y: 1 } }
let b = Object.assign({}, a)
console.log(a)//{ c: 1, z: { y: 1 } }
console.log(b)//{ c: 1, z: { y: 1 } }


浅拷贝就是对b新建了一个对象{c = a.c,z = a.z},对a里面的内容一一赋值到b

这里很关键,如果你对上文中提到的对象数据类型和基本数据类型的赋值有所理解就会知道

赋值c是基本数据类型的赋值,赋值z是对象数据类型的赋值


image.png

然后进行修改

let a = { c: 1, z: { y: 1 } }
let b = Object.assign({}, a)
console.log(a)//{ c: 1, z: { y: 1 } }
console.log(b)//{ c: 1, z: { y: 1 } }
//三个操作,基本数据类型的赋值,对象数据类型的赋值,基本数据类型的添加没有用到赋值
b.c = 2
b.z.y = 2
b.d = 2
//一一看赋值的属性
//b中的c是基本数据类型,原本指向a中的c,但是改变了指向指向了2
//b中的z是对象类型的赋值,修改的是和a中的z同一个对象,因此联动
//b中的d不是赋值来的,与a里面的内容无关
console.log(a)//{ c: 1, z: { y: 2 } }
console.log(b)//{ c: 2, z: { y: 2 } , d : 2 }

以上代码用图如何理解呢?当b对a进行浅拷贝时,等于b新建了一个空间,对a的内容属性逐一进行指针拷贝,如果遇到基本数据类型等于是深拷贝,遇到对象数据类型等于是赋值,因为a和b不是一个空间,因此b添加d属性不会影响到a。


image.png

深拷贝


深拷贝是通过复制创造避开赋值带来的连锁反应,创造一个完全一样的对象,两个对象不会引起关联与变化。常见实现方式:JSON.parse(JSON.stringify())。

回过头看我们的对象数据类型的赋值,如果我们的b的是创建来的,那么与a无关不会引发联动

let a = { c: 1 }
let b = { c: 1 }
console.log(a)//{ c: 1 }
console.log(b)//{ c: 1 }
b.c = 2
b.d = 2
//a没改变
console.log(a)//{ c: 1 }
console.log(b)//{ c: 2, d: 2 }

但是你会说这与深拷贝无关啊?拷贝过程呢?别急,如果你想拿a的数据来用啊,深拷贝是转变成字符串再转回对象,这个对象等于新建的,与a无关,这就是把a拿来深拷贝了。

let a = { c: 1 }
//用深拷贝,等同于let b = { c: 1 }
let b = JSON.parse(JSON.stringify(a))
console.log(a)//{ c: 1 }
console.log(b)//{ c: 1 }
b.c = 2
b.d = 2
//a没改变
console.log(a)//{ c: 1 }
console.log(b)//{ c: 2, d: 2 }
相关文章
|
前端开发 API
(WEB前端编辑DWG)在线CAD如何实现图形识别功能
mxcad 提供的图形识别功能可帮助用户快速识别和提取 CAD 图纸中的各种图形,如直线、多段线、弧线、圆及图块,显著提升设计效率。此功能不仅适用于图形分类,还能进行数量统计和快速定位,减少手动操作。用户可通过 API 进行二次开发,自定义识别逻辑。具体步骤包括打开在线示例、选择识别功能、设置识别参数并开始识别。更多开发文档请关注公众号:梦想云图网页 CAD。
|
自然语言处理 前端开发 开发者
|
运维 安全 Java
主机入侵痕迹排查指导手册(一)排查概述、排查思路
【8月更文挑战第11天】此文档提供了一线服务交付人员在攻防演练期间对主机进行入侵痕迹排查的指导。主要内容包括:1) 排查概述,明确了手册的目标是传递知识与经验,帮助一线人员高效完成排查工作;2) 排查思路,首先介绍排查流程,强调从网络连接、进程信息等多角度入手;其次提出注意事项,如避免误操作导致业务中断,以及在发现疑似异常文件时应谨慎处理。该指南适用于Windows与Linux系统,并关注Web应用的安全检查。
405 0
|
JavaScript 前端开发 容器
用HTML DOM实现有条件地渲染网页元素(上)
用HTML DOM实现有条件地渲染网页元素(上)
|
Java 对象存储 开发者
微服务世界的双雄争霸:Spring Cloud与Netflix OSS——谁将引领下一次企业级应用变革的风暴?
Spring Cloud与Netflix OSS是微服务架构的核心组件集,分别以其与Spring Boot的紧密集成及为大规模分布式系统设计的特性,在Java开发社区中广受青睐。前者通过Eureka提供服务发现机制,简化服务注册与定位;后者借助Hystrix增强系统弹性和可靠性,避免雪崩效应。此外,二者还包含负载均衡(Ribbon)、声明式HTTP客户端(Feign)及API网关(Zuul)等功能,共同构建强大微服务体系,助力开发者聚焦业务逻辑,提升系统灵活性与性能。
262 0
|
算法
数据结构和算法学习记录——二叉搜索树的插入操作、删除操作
数据结构和算法学习记录——二叉搜索树的插入操作、删除操作
238 0
|
Java 数据库连接
Java中的静态代码块深入解析
Java中的静态代码块深入解析
305 0
|
XML JavaScript 前端开发
Web 扫描神器:WhatWeb 保姆级教程(附链接)
Web 扫描神器:WhatWeb 保姆级教程(附链接)
|
监控 数据可视化 前端开发
SpringBoot - 构建监控体系03_使用 Admin Server 管理 Spring 应用程序
SpringBoot - 构建监控体系03_使用 Admin Server 管理 Spring 应用程序
385 0
SpringBoot - 构建监控体系03_使用 Admin Server 管理 Spring 应用程序
|
安全 搜索推荐 领域建模
一文说透子域和限界上下文
一文说透子域和限界上下文
1104 1