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

js-17-对数组、对象进行浅拷贝和深拷贝

目录

  • 数组
    • 一、浅拷贝
      • 1. 展开运算符...
      • 2. Array.prototype.slice()
    • 二、深拷贝
      • 1. JSON方法
      • 2. 递归函数
  • 对象
    • 一、浅拷贝
      • 1. Object.assign()
      • 2. 展开运算符...
    • 二、深拷贝
      • 1. JSON方法
      • 2. 递归函数

自己总结的一些方法,可能有不到位的地方,欢迎指出

数组

一、浅拷贝

1. 展开运算符…

let arr1 = [1,2,'3',true, { name: '李华'}]
let arr2 = [...arr1] // arr2=[1,2,'3',true, { name: '李华'}]arr2[0] = 0 // 修改浅拷贝数组中的基本类型元素,原始数组不受影响
arr2[3] = false // 修改浅拷贝数组中的基本类型元素,原始数组不受影响
arr2[4].name = '小帅' // 修改浅拷贝数组中的对象的属性,由于对象是引用类型,所以原始数组中的对象也会受到影响console.log(arr1) // [1,2,'3',true, { name: '小帅'}]
console.log(arr2) // [0,2,'3',false,{ name: '小帅'}]

2. Array.prototype.slice()

let arr1 = [1, 2, '3', true, { name: '李华'}]
let arr2 = arr1.slice() // arr2=[1,2,'3',true,{ name: '李华'}]arr2[0] = 0
arr2[3] = false
arr2[4].name = '小帅'console.log(arr1) // [1, 2, '3', true, { name: '小帅' }]
console.log(arr2) // [0, 2, '3', false, { name: '小帅' }]

二、深拷贝

1. JSON方法

注意:此方法不能处理函数、undefined、Symbol和循环引用

    let arr1 = [1, 2, '3', true, { name: '李华'}]let arr2 = JSON.parse(JSON.stringify(arr1))arr2[0] = 0arr2[3] = falsearr2[4].name = '小帅'console.log(arr1) // [1, 2, '3', true, { name: '李华'}]console.log(arr2) // [0, 2, '3', false, { name: '小帅'}]

2. 递归函数

    function deepClone(obj, hash = new WeakMap()) {if (obj === null) return nullif (obj instanceof Date) return new Date(obj) // 如果是日期对象,则直接返回一个新的日期对象if (obj instanceof RegExp) return new RegExp(obj) // 如果是正则对象,则直接返回一个新的正则对象// 如果循环引用了就用 weakMap 来解决  if (hash.has(obj)) return hash.get(obj);let allDesc = Object.getOwnPropertyDescriptors(obj);let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc);hash.set(obj, cloneObj);for (let key of Reflect.ownKeys(obj)) {if (typeof obj[key] === 'object' && obj[key] !== null) {cloneObj[key] = deepClone(obj[key], hash); // 递归复制  } else {cloneObj[key] = obj[key];}}return cloneObj;}let arr1 = [1, 2, '3', true, { name: '李华' }, undefined]let arr2 = deepClone(arr1)arr2[4].name = '小帅'console.log(arr1) // [1, 2, '3', true, { name: '李华' }, undefined]console.log(arr2) // [1, 2, '3', true, { name: '小帅' }, undefined]

对象

一、浅拷贝

1. Object.assign()

    let obj1 = {a: 1, b: {c: 2}}let obj2 = Object.assign({}, obj1) // obj2={a:1, b: {c:2}}obj2.a = 100obj2.b.c = 200console.log(obj1) // { a: 1, b: { c: 200 } }console.log(obj2) // { a: 100, b: { c: 200 } }

2. 展开运算符…

    let obj1 = {a: 1, b: {c: 2}}let obj2 = {...obj1}obj2.a = 100obj2.b.c = 200console.log(obj1) // { a: 1, b: { c: 200 } }console.log(obj2) // { a: 100, b: { c: 200 } }

二、深拷贝

1. JSON方法

    let obj1 = {a: 1,b: {c: 2},d: [3, 4],e: undefined, // 注意此方法undefined不会被复制f: function(){ console.log('Hello world')} // 注意此方法函数不会被复制}let obj2 = JSON.parse(JSON.stringify(obj1))// console.log(obj2) // {a:1, b: {c:2}, d: [3,4]}obj2.b.c = 200obj2.d[0] = 300console.log(obj1) // { a: 1, b: { c: 2 }, d: [3, 4], e: undefined, f: f()}console.log(obj2) // { a: 1, b: { c: 200 }, d: [300, 4] }

2. 递归函数

    function deepClone(obj, hash = new WeakMap()) {// 处理基本数据类型和null  if (obj === null || typeof obj !== 'object') {return obj;}// 处理日期和正则对象  if (obj instanceof Date) {return new Date(obj);}if (obj instanceof RegExp) {return new RegExp(obj);}// 如果已经处理过这个对象,则直接返回缓存的结果  if (hash.has(obj)) {return hash.get(obj);}// 根据obj的类型创建一个新的对象或数组  let cloneObj = Array.isArray(obj) ? [] : {};hash.set(obj, cloneObj); // 将原始对象和克隆对象存储在hash中,以处理循环引用  // 递归复制对象的每个属性  for (let key in obj) {if (obj.hasOwnProperty(key)) {cloneObj[key] = deepClone(obj[key], hash);}}// 如果obj是Map或Set,则需要特殊处理  if (obj instanceof Map) {cloneObj = new Map();obj.forEach((value, key) => {cloneObj.set(deepClone(key, hash), deepClone(value, hash));});} else if (obj instanceof Set) {cloneObj = new Set();obj.forEach(value => {cloneObj.add(deepClone(value, hash));});}return cloneObj;}let obj1 = {a: 1,b: {c: 2},d: [3, 4],e: undefined, // 注意此方法undefined不会被复制f: function () { console.log('Hello world') } // 注意此方法函数不会被复制,而且其实通常不深拷贝函数}let obj2 = deepClone(obj1)// console.log(obj2) // { a: 1, b: { c: 2 }, d:[3, 4], e:undefined, f:f()}obj2.b.c = 200obj2.d[0] = 300console.log(obj1) // { a: 1, b: { c: 2 }, d: [3, 4], e: undefined, f: f()}console.log(obj2) // { a: 1, b: { c: 200 }, d: [300, 4], e: undefined, f: f() }

相关文章:

js-17-对数组、对象进行浅拷贝和深拷贝

目录 数组一、浅拷贝1. 展开运算符...2. Array.prototype.slice() 二、深拷贝1. JSON方法2. 递归函数 对象一、浅拷贝1. Object.assign()2. 展开运算符... 二、深拷贝1. JSON方法2. 递归函数 自己总结的一些方法,可能有不到位的地方,欢迎指出 数组 一、…...

Ubuntu24.04中安装Electron

1. 安装Nodejs 使用代理服务从github下载并执行Nodejs安装脚本(假设代理服务器为192.168.2.150:10792) curl -x 192.168.2.150:10792 -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash #注意,Nodejs官网的安装命令少了下面这一行: …...

CPU中也应用到了缓存:CPU3层高速缓存,以及它的缓存一致性问题、MESI协议和Java的一些应用

为什么需要cpu高速缓存? 缓存,一般是为了用来协调两端的数据传输效率差(也可以归纳为性能差),提升响应速度。那么CPU的高速缓存是用来协调什么之间的速度差呢? CPU在处理一条指令的时候,会读写…...

如何使用开发者工具捕获鼠标右键点击事件

要使用浏览器的开发者工具捕获鼠标右键点击事件,请按照以下步骤操作: 打开开发者工具 在大多数浏览器中,您可以按 F12 键或右键单击页面并选择"检查"或"检查元素"。 切换到 Console 标签页 在开发者工具中,找到并点击 “Console” 标签。 添加事件监听器…...

【几何】个人练习-Leetcode-1453. Maximum Number of Darts Inside of a Circular Dartboard

题目链接:https://leetcode.cn/problems/maximum-number-of-darts-inside-of-a-circular-dartboard/description/ 题目大意:给出一系列点和一个圆的半径,(寻找一个圆心)求这个半径的圆最多能覆盖多少个点。 思路&…...

啤酒:从饮品到文化的演变

在人类饮品的长河中,啤酒以其不同的魅力走过了一段漫长的历史旅程。它不仅仅是一种简单的饮品,更是一种文化的象征,一种生活的态度。今天,我们将一起追溯啤酒从单一的饮品到丰富文化的演变过程,并感受Fendi Club精酿啤…...

Java 中 Map 常用类和数据结构详解

1. 引言 在Java编程中,Map是一种重要的数据结构,广泛应用于各种场景,Map实现了键值对(key-value)的存储方式,使得开发者能够快速检索、更新和操作数据。本篇文章将详细讲解Java中常用的Map类及其底层数据结…...

实时监控,动态调整 —— 淘宝商品详情API助力商家实现灵活经营

在讨论实时监控和动态调整的策略时,虽然我不能直接提供淘宝商品详情API的具体代码(因为这通常涉及商业机密和API密钥等敏感信息),但我可以给出一个概念性的示例,说明如何使用这类API来辅助商家实现灵活经营。 概念性示…...

WebGL常用接口和事件

目录 初始化WebGL上下文清除缓冲区缓冲区对象着色器和程序属性指针渲染事件监听错误处理纹理映射...

Golang | Leetcode Golang题解之第429题N叉树的层序遍历

题目: 题解: func levelOrder(root *Node) (ans [][]int) {if root nil {return}q : []*Node{root}for q ! nil {level : []int{}tmp : qq nilfor _, node : range tmp {level append(level, node.Val)q append(q, node.Children...)}ans append(a…...

数据库的全透明加密和半透明加密主要是针对数据存储安全的不同处理方式

数据库的全透明加密和半透明加密主要是针对数据存储安全的不同处理方式。 全透明加密(也称作无损加密或自动加密)就像是给文字戴上了一层无形的面具。在用户看来,他们在数据库中输入的是明文(比如姓名、密码)&#xf…...

MySQL的登录、访问、退出

一、登录: 访问MySQL服务器对应的命令:mysql.exe ,位置:C:\Program Files\MySQL\MySQL Server 8.0\bin (mysql.exe需要带参数执行,所以直接在图形界面下执行该命令会自动结束) 执行mysql.exe命令的时候出…...

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-25

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-09-25 1. PromSec: Prompt Optimization for Secure Generation of Functional Source Code with Large Language Models (LLMs) M Nazzal, I Khalil, A Khreishah, NH Phan - arXiv preprint arXiv:2409.12699, 2…...

PyTorch框架安装

安装 pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple 介绍 PyTorch 一个 Python 深度学习框架,它将数据封装成张量(Tensor)来进行处理。 PyTorch 中的张量就是元素为 同一种数据 类型的多维矩阵。在 PyTorch 中&#xff0…...

分布式锁优化之 使用lua脚本改造分布式锁保证判断和删除的原子性(优化之LUA脚本保证删除的原子性)

文章目录 1、lua脚本入门1.1、变量:弱类型1.2、流程控制1.3、在lua中执行redis指令1.4、实战:先判断是否自己的锁,如果是才能删除 2、AlbumInfoApiController --》testLock()3、AlbumInfoServiceImpl --》testLock() 1、lua脚本入门 Lua 教程…...

从安防视频监控行业发展趋势看EasyCVR平台如何驱动行业智能升级

一、市场规模持续增长 随着科技的进步和社会安全意识的提升,安防视频监控行业市场规模持续增长。据市场研究数据显示,全球智能视频监控市场规模已超过千亿美元,并有望在未来几年内保持高速增长。在中国市场,随着智慧城市、工业互…...

TIOBE 编程指数 9 月排行榜公布 VB.Net第七

原文地址:百度安全验证 IT之家 9 月 8 日消息,TIOBE 编程社区指数是一个衡量编程语言受欢迎程度的指标,评判的依据来自世界范围内的工程师、课程、供应商及搜索引擎,今天 TIOBE 官网公布了 2024 年 9 月的编程语言排行榜&#xf…...

如何用ChatGPT制作一款手机游戏应用

有没有想过自己做一款手机游戏,并生成apk手机应用呢?有了人工智能,这一切就成为可能。今天,我们就使用ChatGPT来创建一个简单的井字棋游戏(Tic-Tac-Toe),其实这个过程非常轻松且高效。 通过Cha…...

0基础学前端 day4

大家好,欢迎来到无限大的频道。 今天继续带领大家开始0基础学前端。 一、 什么是Bootstrap框架? Bootstrap是一个开源前端框架,于2011年由Twitter的开发团队开发并发布。其主要目的是简化开发过程,并使开发者能够轻松快速地构建…...

功能测试详解

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、测试项目启动与研读需求文档 (一) 组建测试团队 1、测试团队中的角色 2、测试团队的基本责任 尽早地发现软件程序、系统或产品中所…...

<Java>String类型变量的使用

两边有一个string就是连接,否则做加法 ‘ ’是char,“ ”是string,char能做加法,string只能连接...

JavaScript可视化

JavaScript 提供了多种库和工具来进行数据可视化。以下是一些流行的可视化库及其特点: D3.js特点: 强大的数据驱动文档(Data-Driven Documents)库,允许创建复杂的交互式图表。使用场景: 适合需要高度自定义和复杂交互的可视化。Chart.js特点: 易于使用的图表库,提供了多种…...

HTML5简介的水果蔬菜在线商城网站源码系列模板3

文章目录 1.设计来源1.1 主界面1.2 商品列表1.3 商品信息1.4 购物车1.5 其他页面效果 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板,程序开发,在线开发,在线沟通 作者:xcLeigh 文章地址:https://blog.csdn.ne…...

传输层TCP协议

一、TCP协议格式 我们看到报头固定有20字节,最后选项大小不固定。 4位首部长度(二进制0000 ~ 1111,十进制范围[0, 15])单位是4字节(存放字节大小范围[0, 60])包括了20字节固定长度 选项长度。若选项大小为…...

自己开发一个网站系列之-网页开发初识

自己开发一个网站系列之-网页开发初识 欢迎来到网页开发的世界!在这个教程中,我们将介绍网页开发的基本概念、工具和技术,让你能够从零开始创建自己的网页。 一、基础概念 1. 什么是网页? 网页是通过互联网进行访问的文档&#…...

【代码随想录训练营第42期 Day61打卡 - 图论Part11 - Floyd 算法与A * 算法

目录 一、Floyd算法与A * 算法 1、Floyd算法 思想 伪代码 2、 A * 算法 思想 伪代码 二、经典题目 题目一:卡码网 97. 小明逛公园 题目链接 题解:Floyd 算法 题目二:卡码网 127. 骑士的攻击 题目链接 题解:A * 算法&a…...

docker和ufw冲突问题

在ubuntu上部署的docker映射的端口,开启防火墙ufw后,在未放通的状态下,还是可以访问 解决办法: 在/etc/docker/daemon.json添加如下配置 {"iptables": false } 然后重启docker服务即可 systemctl daemon-reload s…...

Java(基本数据类型)( ̄︶ ̄)↗

Java 基本数据类型是Java编程语言中用于存储数据值的基本单位。它们直接映射到硬件的处理器上,因此访问速度非常快。Java中的基本数据类型分为四大类:整型、浮点型、字符型、布尔型。每种类型都有其固定的范围和存储大小。 一、整型 1)byte…...

283. 移动0

class Solution(object):def moveZeroes(self, nums):""":type nums: List[int]:rtype: None Do not return anything, modify nums in-place instead."""# 两个指针,left, right,中间夹的都是0,# 像个虫子一样一纵一纵的…...

Mysql删库跑路,如何恢复数据?

问题 删库跑路,数据还能恢复吗? 我们经常听说某某被领导训斥了,对领导心生痛恨,然后登录 Mysql 删库跑路。对于闲聊中经常听说过的一个段子,在现实生活中是否真的发生过,如果发生了,我们该如何解…...