深拷贝和浅拷贝对比

news2024/12/26 21:13:23

 JavaScript存储引用数据(对象)都是存地址的,存放在堆内存中的对象,在栈内存中存的是一个指针,这个指针指向堆内存一个位置。再从堆内存中取得所需的数据。

 深拷贝:对数据进行拷贝之后,修改拷贝之后的数据原数据不会发生改变,新数据在堆内存中重新开辟出来一个新的地址,两层数据保存的地址是独立的,所以数据互不影响。

浅拷贝:对数据进行拷贝之后,修改拷贝之后的数据原数据也会改变,新数据和原数据在栈内存中以指针的形式存储,并且同时指向了堆内存中同一个地址,所以修改拷贝之后的数据原数据也会改变,业务场景中浅拷贝经常会发生数据冲突

浅拷贝原理图 

下面以举例子的形式,对比深拷贝和浅拷贝,以便于理解的更详细

对简单数据类型进行赋值修改

let c = 2
let b = c
b+=5
console.log(c,b) // 2,7

现象:简单数据类型之间的值没有互相影响

对引用数据类型进行拷贝

let a = { name: 'ggc' }
let b = a
b.name = 'lnw'
console.log(a, b)

let arr = [1,2,3]
let arr2 = arr
arr2.push(99)
console.log(arr,arr2)

 现象:当修改了声明的引用类型b和arr2时,原始的数据也发生了改变,这属于浅拷贝。

解释分析:浅拷贝只会发生在引用类型身上,对于引用类型如果之进行简单的赋值,只会赋值指向堆内存的指针,这种称为浅拷贝。而深拷贝就是完全拷贝一个引用类型,为不是地址指针。

那我们在拷贝原始数据时肯定是不希望对原始数据进行修改的,因为影响到原来的数据了,这种情况怎么办呢?

深拷贝就上场了

1.通过JSON.stringify和JSON.parse

可以深拷贝的数组和对象,但是不能拷贝函数,可以进行对象或者数组的嵌套拷贝。

缺点:无法实现对对象中方法的深拷贝

 由此可以看出由此可以看出函数是没有办法拷贝的

 2. 利用扩展运算符进行深拷贝

缺点:无法对对象里面嵌套的对象进行深拷贝,相当于只是对一层引用对象进行深拷贝

 

 3.手写递归深拷贝函数

//使用递归实现深拷贝
   function deepClone(obj) {
       //判断拷贝的obj是对象还是数组
       var objClone = Array.isArray(obj) ? [] : {};
       if (obj && typeof obj === "object") { //obj不能为空,并且是对象或者是数组 因为null也是object
           for (key in obj) {
               if (obj.hasOwnProperty(key)) {
                   if (obj[key] && typeof obj[key] === "object") { //obj里面属性值不为空并且还是对象,进行深度拷贝
                       objClone[key] = deepClone(obj[key]); //递归进行深度的拷贝
                   } else {
                       objClone[key] = obj[key]; //直接拷贝
                   }
               }
           }
       }
       return objClone;
   }

 举例:

      var arr = {
         name: '浪漫主义码农',
         age: 20,
         adress: ['jiangxi', 'changsha'],
         friends: {
             friend1: '张三',
             friend2: '李四'
         },
         fun: function(){
             console.log("我是" + this.name + "的对象")
         }
     }
     var brr = deepClone(arr)
     brr.name = '法外狂徒张三'
     brr.adress[0] = '长沙'
     console.log("arr为", arr)
     arr.fun()
     console.log("brr为", brr)
     brr.fun()
 ​
     //使用递归实现深拷贝
     function deepClone(obj) {
         //判断拷贝的obj是对象还是数组
         var objClone = Array.isArray(obj) ? [] : {};
         if (obj && typeof obj === "object") { //obj不能为空,并且是对象或者是数组 因为null也是object
             for (key in obj) {
                 if (obj.hasOwnProperty(key)) {
                     if (obj[key] && typeof obj[key] === "object") { //obj里面属性值不为空并且还是对象,进行深度拷贝
                         objClone[key] = deepClone(obj[key]); //递归进行深度的拷贝
                     } else {
                         objClone[key] = obj[key]; //直接拷贝
                     }
                 }
             }
         }
         return objClone;
     }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/189097.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python:从协议到抽象基类

本章话题是接口:鸭子类型代表特征动态协议; 使接口更明确、能验证实现是否副了规定的抽象基类ABC(Abstact Base Class).Python语言诞生15年后,Python2.6中才引入了抽象基类,抽象基类。对于java、C#类似的语言,会觉得鸭…

DevSecOps敏捷安全技术金字塔V3.0正式发布

2022年12月28日,由悬镜安全主办,3S-Lab软件供应链安全实验室、Linux基金会OpenChain社区、ISC、OpenSCA社区联合协办的第二届全球DevSecOps敏捷安全大会(DSO 2022)已通过全球直播的形式圆满举行。本届大会以“共生敏捷进化”为主题…

HTB_Markup_xml注入读ssh私钥进程注入

文章目录信息收集xml注入ssh 私钥连接提权信息收集 使用如下参数可以探测具体版本,只使用-sV -v无此效果 nmap -sC -A -Pn 10.129.95.192是个登录页面 弱口令,只有admin-password成功登录 几个页面,只有order.php页面可以与后端交互并传递x…

【Kubernetes 企业项目实战】06、基于 Jenkins+K8s 构建 DevOps 自动化运维管理平台(中)

目录 一、基于 Jenkinsk8sGitDocker Hub 等技术链构建企业级 DevOps 容器云平台 1.1 安装 Jenkins 1.1.1 安装 nfs 服务 1.1.2 在 kubernetes 中部署 jenkins 1.2 配置 Jenkins ​1.2.1 获取管理员密码 1.2.2 安装插件 1.2.3 创建第一个管理员用户 1.3 测试 jenkins 的…

VMware Workstation中安装Kali 2022

VMware Workstation中安装Kali 2022 前言 开工了,笔记本中的相关工具该更新了,今天记录一下。 首先记录的是在VMware Workstation中安装kali,这个过程比较简单。 我只是想扩充一下自己的博客,另外可以给入门人员一个参考。 下载…

react的JSX语法

1.jsx基本使用 1 createElement() 的问题 繁琐不简洁。不直观,无法一眼看出所描述的结构。不优雅,用户体验不爽。 2 JSX 简介 JSX 是 JavaScript XML 的简写,表示在 JavaScript 代码中写 XML(HTML) 格式的代码。 优…

通信原理笔记—增量调制(∆M)

目录 概述: 简单增量调制(∆M)原理: 编码器与解码器 简单△M的过载问题: 增量总和(∆-Σ)调制 数字压扩自适应增量调制: 不同编码调制方式的误码性能分析: 概述: 最简单的DPCM是增量调制&#xff0c…

layui框架学习(4:导航)

layui官网教程采用html中的无序列表和定义列表来实现导航样式(文章最后还有个关于导航所用元素的补充说明),主要包括水平导航、垂直/侧边导航,同时还支持用span和a元素实现面包屑导航样式。导航功能需要加载element模块&#xff0…

实验二:Linux主机漏洞利⽤攻击实践

(一)实验简介 实验所属系列:windows主机漏洞利用攻击实践 实验对象:本科/专科信息安全专业 相关课程:渗透测试 实验时数(学分):2学时 实验类别:实践类 (二&a…

如何集中式管理多个客户端节点传输任务-镭速

在一些生产制造企业或it部门,它们的生产机器设备每天都会有大量的生产数据,并且需要人为地对这些数据进行迁移或者归档备份到其他存储。这样重复性的操作,无疑大大提高了人工成本,而且运作起来的效率也不高。 镭速服务器集中式任务…

MySQL优化方案

一、MySQL 的优化方案有哪些?MySQL 数据库常见的优化手段分为三个层面:SQL 和索引优化、数据库结构优化、系统硬件优化等,每个大的方向中又包含多个小的优化点。1.SQL 和索引优化通过优化 SQL 语句以及索引来提高 MySQL 数据库的运行效率① 使…

【UE5】动画系统

title: 【UE5】动画系统 date: 2023-01-31 19:50:47 tags: UE5 categories: 学习笔记 password: abstract: message: 最近接触的项目涉及到动捕和动画,以前接触的范围主要是GamePlay以及C和蓝图的交互,很少接触动画,借此机会学习一下UE5的动…

【Jmeter】报错解决:JedisException: Could not return the broken resource to the pool

一、报错详情 (1)报错场景 使用 Jmeter 插件 Redis Data Set 配置连接 Redis 数据池时,运行出现报错 (2)报错日志

Python对liunx中mysql数据库进行单表查询 10个案例带你了解

关于Python连接liunx中mysql数据库的方式在这一篇文章 这里写目录标题1.在Liunx服务器中的mysql新建一个表2.插入数据3.连接liunx中的mysql数据库1、查询1946班的成绩信息2,查询1944班,语文成绩大于60小于90的成绩信息3,查询学生表中1到6行的…

QTabWidget 美化 qss

1. tab, tab-bar, pane属性分布 2. 使用qss美化时,tab标签上和pane中都能美化成功,但tab最右侧的tab-bar却始终没有成功。 /*设置控件的背景*/ QTabWidget {background-color:rgb(4,138,224); } /*设置控件下面板的背景颜色*/ QT…

C++11 常用的新特性

本篇介绍C11标准对比之前C标准的新特性,C11为C语言在2011年发布的版本,它改进幅度很大,影响至今。如加入auto 关键字、nullptr、移动语义(move semantics)、委托构造函数(delegating constructors&#xff…

ChatGPT超详细注册与使用教程

文章目录前言一、ChatGPT账号注册二、SMS-ACTIVATE虚拟手机号验证三、ChatGPT使用总结前言 最近ChatGPT非常火爆,是一种革命性的技术,这也吸引来了很多人想尝试一下,但是由于并没有在国内开通这项服务,所以国内的用户无法使用Chat…

Javascript预解析

1.我们js引擎运行js 分为两步,1.预解析,2.执行代码 (1)预解析:js引擎会把js里面所有的var还有function提升到当前作用域发的前面 (2)执行代码:按照代码书写的顺序从上往下执行 2.预…

RK3588平台开发系列讲解(进程篇)进程的处理器亲和性

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、简介二、相关结构体三、函数接口四、cpuset的使用沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇介绍进程的处理器亲和性相关知识。 一、简介 Linux进程调度器为了充分利用CPU资源,会将进程在不同的…

如何养成整洁的代码习惯

如何养成整洁的代码习惯前言1.为什么要保持代码整洁?1.1 所以从一开始就要保持整洁1.2 如何写出整洁的代码?2.命名2.1 不好的命名方式1.没有任何意义的命名方式2.命名前后不一致3.命名冗余3.类3.1单一职责3.2 开闭原则3.3 内聚4.函数4.1 只做一件事4.2 函数命名1.函数名应见名…