当前位置: 首页 > 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、测试团队的基本责任 尽早地发现软件程序、系统或产品中所…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM&#xff09…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...