当前位置: 首页 > news >正文

js——浅拷贝和深拷贝

一、浅拷贝

浅拷贝:拷贝的是地址

常见方法:

1.拷贝对象:0bject.assgin()/展开运算符 {...obj}拷贝对象

2.拷贝数组:Array.prototype.concat()或者[...arr]

  <script>const obj = {uname: 'yan',age: 22,family: {sister: 'yu'}}// 浅拷贝  如果是简单数据类型拷贝值,引用数据类型拷贝的是地址(简单理解:如果是单层对象,没问题,如果有多层就有问题)// // ...obj // const o = { ...obj }// console.log(o);// o.age = 20// console.log(o);// console.log(obj);// Object.assignconst o1 = {}Object.assign(o1, obj)o1.age = 18o1.family.sister = 'xin'console.log(o1);console.log(obj);</script>

总结:

1.直接赋值和浅拷贝有什么区别?

直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对象栈里面的地址

浅拷贝如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响

2.浅拷贝怎么理解?

拷贝对象之后,里面的属性值是简单数据类型直接拷贝值

如果属性值是引用数据类型则拷贝的是地址

二、深拷贝

深拷贝:拷贝的是对象,不是地址

常见方法:

1.通过递归实现深拷贝

2.lodash/cloneDeep

3.通过JSON.stringify()实现

下面介绍一下几种方法:

(1)利用递归

函数递归:
如果一个函数在内部可以调用其本身,那么这个函数就是递归函数

· 简单理解:函数内部自己调用自己,这个函数就是递归函数
· 递归函数的作用和循环效果类似
· 由于递归很容易发生“栈溢出”错误(stackoverflow),所以必须要加退出条件 

<script>const obj = {uname: 'yan',age: 22,hobby: ['唱歌', '跳舞'],family: {sister: 'yu'}}const o = {}// 深拷贝需要用到函数递归,新对象修改不会影响旧对象function deepCopy(newObj, oldObj) {for (let k in oldObj) {// 处理数组问题:利用递归函数取出数组再次遍历  注意:一定先写数组,再写对象if (oldObj[k] instanceof Array) {newObj[k] = []// newObj[k] 接受空数组[]// oldObj[k] ['唱歌', '跳舞']deepCopy(newObj[k], oldObj[k])// 处理对象问题} else if (oldObj[k] instanceof Object) {newObj[k] = {}deepCopy(newObj[k], oldObj[k])} else {// k 属性名   oldObj[k]属性值// newObj[k] === o.unamenewObj[k] = oldObj[k]}}}deepCopy(o, obj)  //函数调用  俩参数 o新对象  obj旧对象o.hobby[0] = '编程'o.family.sister = 'xin'console.log(o);console.log(obj);</script>

(2)利用lodash:引入js库 lodash

<script src="./lodash.min.js"></script><script>const obj = {uname: 'yan',age: 22,hobby: ['唱歌', '跳舞'],family: {sister: 'yu'}}const o = _.cloneDeep(obj)console.log(o);</script>

(3)利用JSON

<script>const obj = {uname: 'yan',age: 22,hobby: ['唱歌', '跳舞'],family: {sister: 'yu'}}// 把对象转换为JSON字符串const o = JSON.parse(JSON.stringify(obj))o.family.sister = 'xin'console.log(o);console.log(obj);</script>

总结:

实现深拷贝三种方式?

自己利用递归函数书写深拷贝

利用js库 lodash里面的_.cloneDeep()

利用JSON字符串转换

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Git多人协作开发】同一分支下的多人协作开发模式
  • springboot配置文件如何读取pom.xml的值
  • 新电脑如何设置 npm 源及查看源、安装 cnpm、pnpm 和 yarn 的详细教程
  • Python研究生毕业设计,数据挖掘、情感分析、机器学习
  • scikit-learn中fit_transform会改变原始数据吗
  • 江科大/江协科技 STM32学习笔记P9-11
  • Si24R03:高度集成的低功耗SOC芯片中文资料
  • 05 ES6中的Set类型
  • openssl req 详解
  • c++——map和set
  • 解决vscode+UE5中vscode无法识别头文件,无法函数无法跳转,也无法自动补全的问题。
  • 科研绘图系列:R语言和弦图 (Chord diagram)
  • 自动驾驶(八十六)---------通信中间件Fdbus
  • C#测试控制台程序调用Quartz.NET的基本用法
  • OpenCV 卷积 Robert算子,Laplance算子,Sobel算子,Canny边缘检测原理
  • 【翻译】babel对TC39装饰器草案的实现
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • es6--symbol
  • Java多态
  • vue2.0项目引入element-ui
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 浅谈web中前端模板引擎的使用
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 原生js练习题---第五课
  • 找一份好的前端工作,起点很重要
  • 智能网联汽车信息安全
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • 《码出高效》学习笔记与书中错误记录
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #define 用法
  • #NOIP 2014# day.1 T2 联合权值
  • #pragma 指令
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (CVPRW,2024)可学习的提示:遥感领域小样本语义分割
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (分布式缓存)Redis分片集群
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (十七)Flink 容错机制
  • (一)utf8mb4_general_ci 和 utf8mb4_unicode_ci 适用排序和比较规则场景
  • (原創) 未来三学期想要修的课 (日記)
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .NET CLR基本术语
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .net 托管代码与非托管代码
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • //usr/lib/libgdal.so.20:对‘sqlite3_column_table_name’未定义的引用
  • /usr/bin/perl:bad interpreter:No such file or directory 的解决办法
  • @private @protected @public