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

30天JS挑战(第十四天)------数据的复制

第十四天挑战(数据的复制)

地址:https://javascript30.com/

所有内容均上传至gitee,答案不唯一,仅代表本人思路

中文详解:https://github.com/soyaine/JavaScript30

该详解是Soyaine及其团队整理编撰的,是对源代码的详解强烈推荐大家观看学习!!!

本人gitee:https://gitee.com/thats-all-right-ha-ha/30-days—js-challenge

官方代码

本期内容是关于基本数据类型和引用数据类型在复制时的特性和解决方法

基础类型

//start with strings, numbers and booleans
let age = 100;
let age2 = age;
console.log(age, age2);
age = 200;
console.log(age, age2);let name = 'Wes';
let name2 = name;
console.log(name, name2);
name = 'wesley';
console.log(name, name2);

分析

  • 基础数据类型:
    • 布尔值(Boolean),有 2 个值分别是:truefalse
    • null,一个表明 null 值的特殊关键字。JavaScript 是大小写敏感的,因此 nullNullNULL或变体完全不同。
    • undefined,和 null 一样是一个特殊的关键字,undefined 表示变量未赋值时的属性。
    • 数字(Number),整数或浮点数,例如: 42 或者 3.14159
    • 任意精度的整数(BigInt),可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。
    • 字符串(String),字符串是一串表示文本值的字符序列,例如:"Howdy"
    • 代表(Symbol,在 ECMAScript 6 中新添加的类型)。一种实例是唯一且不可改变的数据类型。
  • 基础数据类型的值均存储在栈中,每个值都有一个独立的内存空间,在a变量复制给b变量的时候复制的是一个具体的值,在a变量进行更改的时候,不会影响到b变量的值

引用类型(数组)

// Let's say we have an array
const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];// and we want to make a copy of it.
const team = players;console.log(players, team);
// You might think we can just do something like this:
// team[3] = 'Lux';// however what happens when we update that array?// now here is the problem!// oh no - we have edited the original array too!// Why? It's because that is an array reference, not an array copy. They both point to the same array!// So, how do we fix this? We take a copy instead!
const team2 = players.slice();// one way// or create a new array and concat the old one in
const team3 = [].concat(players);// or use the new ES6 Spread
const team4 = [...players];
team4[3] = 'heeee hawww';
console.log(team4);const team5 = Array.from(players);// now when we update it, the original one isn't changed

分析

  • 引用类型(数组)
  • 一般情况下引用类型的值会作为数据的有序或无序集合即一个数组中包含着许多的数据,通常他们的数据体量都较为庞大,所以一般引用类型的数据都存放在堆内存中,并且在栈内存中开辟一个地址单元指向其堆内存中的地址
  • 在数组进行复制的时候,本质上复制的是数组在堆内存中的地址,也就是 teamplayers这两个变量指向的是同一个数组,那么当其中一个对其进行改变的时候,另一个也会受到一定的影响
  • 那么如何解决这个问题?
    • slice方法:slice方法会返回一个新的数组,这个数组的值是原数组的浅拷贝,slice的返回的数组和原数组是两个数组,不会造成影响
    • concat:方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组
    • 展开运算符
    • 创建新的数组实例

引用类型(对象)

// with Objects
const person = {
name: 'Wes Bos',
age: 80
};// and think we make a copy:
// const captain = person;
// captain.number = 99;// how do we take a copy instead?
const cap2 = Object.assign({}, person, { number: 99, age: 12 });
console.log(cap2);// We will hopefully soon see the object ...spread
// const cap3 = {...person};// Things to note - this is only 1 level deep - both for Arrays and Objects. lodash has a cloneDeep method, but you should think twice before using it.const wes = {
name: 'Wes',
age: 100,
social: {
twitter: '@wesbos',
facebook: 'wesbos.developer'
}
};console.clear();
console.log(wes);const dev = Object.assign({}, wes);const dev2 = JSON.parse(JSON.stringify(wes));

分析

  • 对象也是引用类型,和数组的存储原理基本一致,这里直接上解决方法
  • 解决方法
  • Object.assign():将一个或者多个源对象中所有可枚举的自有属性复制到目标对象,并返回修改后的目标对象。
  • JSON.parse & JSON.stringify:后者将对象转换成字符串,前者将字符串再复原成对象

扩展知识

引用类型的深拷贝

数组和对象的深拷贝在JavaScript中是一个常见需求,尤其是在处理复杂数据结构时,以确保原始数据不被无意修改。深拷贝意味着复制对象及其嵌套对象的实际值,而不仅仅是复制引用地址。以下是实现深拷贝的几种方法:

1. 使用 JSON.stringify()JSON.parse()

这种方法简单易用,但是有其局限性,比如不能复制函数、undefined、Symbol、循环引用等。

javascriptCopy codeconst obj = {a: 1,b: {c: 2,d: 3,},
};const arr = [1, [2, 3], { a: 4 }];const deepCopiedObj = JSON.parse(JSON.stringify(obj));
const deepCopiedArr = JSON.parse(JSON.stringify(arr));// 修改深拷贝后的对象和数组,不会影响原始数据
deepCopiedObj.b.c = 20;
deepCopiedArr[1][0] = 200;console.log(obj.b.c); // 输出 2
console.log(arr[1][0]); // 输出 2

2. 使用递归

递归方法可以更灵活地处理各种数据类型,包括数组和对象,但需要手动实现。

javascriptCopy codefunction deepCopy(value, hash = new WeakMap()) {if (typeof value !== 'object' || value === null) {return value;}if (hash.has(value)) {return hash.get(value);}let copy = Array.isArray(value) ? [] : {};hash.set(value, copy);for (let key in value) {if (value.hasOwnProperty(key)) {copy[key] = deepCopy(value[key], hash);}}return copy;
}const obj = { a: 1, b: { c: 2 } };
const arr = [1, [2, 3], { a: 4 }];const deepCopiedObj = deepCopy(obj);
const deepCopiedArr = deepCopy(arr);deepCopiedObj.b.c = 20;
deepCopiedArr[1][0] = 200;console.log(obj.b.c); // 输出 2
console.log(arr[1][0]); // 输出 2

3. 使用 structuredClone()

从 ES2021 开始,structuredClone() 方法提供了一种官方、高效的深拷贝解决方案,支持大多数数据类型,包括循环引用,但不支持复制函数。

javascriptCopy codeconst obj = { a: 1, b: { c: 2 } };
const arr = [1, [2, 3], { a: 4 }];const deepCopiedObj = structuredClone(obj);
const deepCopiedArr = structuredClone(arr);deepCopiedObj.b.c = 20;
deepCopiedArr[1][0] = 200;console.log(obj.b.c); // 输出 2
console.log(arr[1][0]); // 输出 2

structuredClone() 是目前最推荐的深拷贝实现方式,因为它既能处理复杂数据结构,包括循环引用,又能通过浏览器和Node.js环境的标准API直接使用。不过,它可能不适用于旧版浏览器或某些特殊环境,需要根据实际情况选择合适的方法。

相关文章:

30天JS挑战(第十四天)------数据的复制

第十四天挑战(数据的复制) 地址:https://javascript30.com/ 所有内容均上传至gitee,答案不唯一,仅代表本人思路 中文详解:https://github.com/soyaine/JavaScript30 该详解是Soyaine及其团队整理编撰的,是对源代码…...

【洛谷 P8682】[蓝桥杯 2019 省 B] 等差数列 题解(数学+排序+辗转相除法)

[蓝桥杯 2019 省 B] 等差数列 题目描述 数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列,只记得其中 N N N 个整数。 现在给出这 N N N 个整数,小明想知道包含这 N N N 个整数的最短的等差数列有几项? 输…...

Linux:kubernetes(k8s)部署CNI网络插件(4)

在上一章进行了node加入master Linux:kubernetes(k8s)node节点加入master主节点(3)-CSDN博客https://blog.csdn.net/w14768855/article/details/136420447?spm1001.2014.3001.5501 但是他们显示还是没准备好 看一下…...

docker save 命令 docker load 命令 快速复制容器

docker save 命令 docker load 命令 1、docker save 命令2、docker load 命令 1、docker save 命令 docker save 命令用于在系统上把正在使用的某个容器镜像 导出成容器镜像文件保存下载,以便在其他系统上导入这个容器镜像文件 以便快速在其他服务器上启动相同的容…...

Apache Flink连载(三十七):Flink基于Kubernetes部署(7)-Kubernetes 集群搭建-3

🏡 个人主页:IT贫道-CSDN博客 🚩 私聊博主:私聊博主加WX好友,获取更多资料哦~ 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录...

【机器学习】实验6,基于集成学习的 Amazon 用户评论质量预测

清华大学驭风计划课程链接 学堂在线 - 精品在线课程学习平台 (xuetangx.com) 代码和报告均为本人自己实现(实验满分),此次代码开源大家可以自行参考学习 有任何疑问或者问题,也欢迎私信博主,大家可以相互讨论交流哟…...

【寸铁的刷题笔记】图论、bfs、dfs

【寸铁的刷题笔记】图论、bfs、dfs 大家好 我是寸铁👊 金三银四,图论基础结合bfs、dfs是必考的知识点✨ 快跟着寸铁刷起来!面试顺利上岸👋 喜欢的小伙伴可以点点关注 💝 🌞详见如下专栏🌞 &…...

vue2 + axios + mock.js封装过程,包含mock.js获取数据时报404状态的解决记录,带图文,超详细!!!

vue axios mock.js 以下是封装的过程,记录一下 1、首先先了解什么是mock.js的用途及特点 官网地址:Mock.js (mockjs.com) 作用:生成随机数据,拦截 Ajax 请求 优势: 2、了解axios的原理及使用 官网地址&#xff1a…...

对象变更记录objectlog工具(持续跟新)

文章目录 前言演示代码演示环境引入项目项目框架操作步骤 设计介绍参考仓库 前言 系统基于mybatis-plus, springboot环境 对于重要的一些数据,我们需要记录一条记录的所有版本变化过程,做到持续追踪,为后续问题追踪提供思路。下面展示预期效果…...

平衡二叉树,二叉树的路径,左叶子之和

第六章 二叉树part04 今日内容: 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和 110.平衡二叉树 (优先掌握递归) 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为&am…...

Sodinokibi勒索病毒最新变种,解密工具更新到2.0版本

Sodinokibi勒索病毒 Sodinokibi勒索病毒又称REvil,自从2019年6月1日,GandCrab勒索病毒运营团伙宣布停止运营之后,Sodinokibi勒索病毒马上接管了GandCrab的大部分传播渠道,同时它也被称为是GandCrab勒索病毒的“接班人”&#xff…...

css 鼠标移入放大的效果

效果 HTML <div class"img-wrap"><img class"img-item" src"../assets/1.png" alt"" srcset""></div> CSS <style lang"less" scoped> .img-wrap {/* 超出隐藏 */overflow: hidden;.img-…...

Transformer模型分布式并行通信量浅析

1.数据并行DP&#xff08;朴素数据并行&#xff0c;Zero数据并行之后补充&#xff09; O ( h 2 ∗ l ) O(h^2*l) O(h2∗l) 每台机器做完自己的梯度后需要做一次All reduce操作来累积梯度&#xff0c;故一个batch计算发送的数据量为每层梯度大小 h 2 h^2 h2乘以层数 l l l 优点…...

PMP考试之20240304

1.一家食品公司正在使用预测型方法开发一种新产品&#xff0c;该产品目前正处于测试阶段。鉴于测试反馈的性质&#xff0c;项目经理决定使用迭代方法。在其中一个迭代结束时&#xff0c;颁布了与该产品有关的新法规。项目经理接下来应该做什么&#xff1f; A.就项目的范围提出…...

智慧城市中的公共服务创新:让城市生活更便捷

目录 一、引言 二、智慧城市公共服务创新的实践 1、智慧交通系统 2、智慧医疗服务 3、智慧教育系统 4、智慧能源管理 三、智慧城市公共服务创新的挑战 四、智慧城市公共服务创新的前景 五、结论 一、引言 随着信息技术的迅猛发展&#xff0c;智慧城市已成为现代城市发…...

bert 相似度任务训练完整版

任务 之前写了一个相似度任务的版本&#xff1a;bert 相似度任务训练简单版本,faiss 寻找相似 topk-CSDN博客 相似度用的是 0&#xff0c;1&#xff0c;相当于分类任务&#xff0c;现在我们相似度有评分&#xff0c;不再是 0,1 了&#xff0c;分数为 0-5&#xff0c;数字越大…...

Ribbon实现Cloud负载均衡

安装Zookeeper要先安装JDK环境 解压 tar -zxvf /usr/local/develop/jdk-8u191-linux-x64.tar.gz -C /usr/local/develop 配置JAVA_HOME vim /etc/profile export JAVA_HOME/usr/local/develop/jdk1.8.0_191 export PATH$JAVA_HOME/bin:$PATH export CLASSPATH.:$JAVA_HOM…...

【UE 材质】制作加载图案(2)

在上一篇&#xff08;【UE 材质】制作加载图案&#xff09;基础上继续实现如下效果的加载图案 效果 步骤 1. 复制一份上一篇制作的材质并打开 2. 添加“Floor”节点向下取整 除相同的平铺数 此时的效果如下 删除如下节点 通过“Ceil”向上取整&#xff0c;参数“Tiling”默认…...

为啥要用C艹不用C?

在很多时候&#xff0c;有人会有这样的疑问 ——为什么要用C&#xff1f;C相对于C优势是什么&#xff1f; 最近两年一直在做Linux应用&#xff0c;能明显的感受到C带来到帮助以及快感 之前&#xff0c;我在文章里面提到环形队列 C语言&#xff0c;环形队列 环形队列到底是怎么回…...

Java:JVM基础

文章目录 参考JVM内存区域程序计数器虚拟机栈本地方法栈堆方法区符号引用与直接引用运行时常量池字符串常量池直接内存 参考 JavaGuide JVM内存区域 程序计数器 程序计数器是一块较小的内存空间&#xff0c;可以看做是当前线程所执行的字节码的行号指示器&#xff0c;各线程…...

VMware 虚拟机网络问题排查与解决方案

VMware 虚拟机网络问题排查与解决方案 问题背景 在项目中时&#xff0c;遇到一个看似 "网络不通" 的问题&#xff1a;Windows 宿主机无法 ping 通虚拟机上的 VIP 地址。 症状表现&#xff1a; 虚拟机可以 ping 通 Windows 宿主机Windows 宿主机无法 ping 通虚拟机…...

2026本科毕业论文工具 TOP10:从选题到答辩,AI 帮你一键通关

毕业季的论文焦虑&#xff0c;几乎是每个本科生逃不开的 “必修课”。选题卡壳、文献堆砌、格式返工、查重降重反复折腾…… 与其硬熬&#xff0c;不如找对工具。今天就给大家整理了10 款超实用的 AI 毕业论文写作工具&#xff0c;尤其是榜首的 Paperxie&#xff0c;堪称本科生…...

3个关键步骤:如何安全备份微信聊天记录并永久保存你的数字记忆?

3个关键步骤&#xff1a;如何安全备份微信聊天记录并永久保存你的数字记忆&#xff1f; 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾因手机丢失、系统升级或意…...

3个核心功能解决抖音内容下载难题:douyin-downloader全解析

3个核心功能解决抖音内容下载难题&#xff1a;douyin-downloader全解析 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback …...

Qwen2.5-0.5B-Instruct实战:Python调用接口代码实例

Qwen2.5-0.5B-Instruct实战&#xff1a;Python调用接口代码实例 想快速上手一个轻量级但功能强大的AI模型吗&#xff1f;今天我们来聊聊阿里开源的Qwen2.5-0.5B-Instruct模型&#xff0c;并手把手教你如何用Python调用它的接口。这个模型虽然参数只有5亿&#xff0c;但在指令遵…...

Oracle 19c RAC环境下备库node1 ADG异常、asm异常分析及处理

在技术领域&#xff0c;我们常常被那些闪耀的、可见的成果所吸引。今天&#xff0c;这个焦点无疑是大语言模型技术。它们的流畅对话、惊人的创造力&#xff0c;让我们得以一窥未来的轮廓。然而&#xff0c;作为在企业一线构建、部署和维护复杂系统的实践者&#xff0c;我们深知…...

XCP标定协议实战:从CAN到以太网的多协议适配指南(附A2L文件解析)

XCP标定协议实战&#xff1a;从CAN到以太网的多协议适配指南&#xff08;附A2L文件解析&#xff09; 在汽车电子开发领域&#xff0c;标定协议如同神经系统般连接着ECU与开发工具。当工程师面对不同硬件平台和传输协议时&#xff0c;如何实现XCP协议的灵活适配成为提升开发效率…...

粒子群算法调参指南:如何避免陷入局部最优(附非线性递减权重实现)

粒子群算法调参实战&#xff1a;非线性权重策略与全局优化技巧 粒子群优化算法&#xff08;PSO&#xff09;作为群体智能领域的经典方法&#xff0c;其性能高度依赖参数配置。许多工程师在基础应用阶段能够获得可接受的结果&#xff0c;但当问题复杂度提升时&#xff0c;常常陷…...

Qt播放MP4视频时,如何优雅地处理播放列表和播放模式?一个实战案例分享

Qt播放MP4视频时如何优雅处理播放列表与播放模式 在开发多媒体应用时&#xff0c;播放列表管理和播放模式切换往往是比基础播放功能更具挑战性的部分。本文将深入探讨如何在Qt框架下构建一个健壮的MP4播放器&#xff0c;重点解决播放列表的智能管理和多种播放模式的优雅实现。…...

从零开始:SDXL 1.0电影级绘图工坊Docker环境搭建与测试

从零开始&#xff1a;SDXL 1.0电影级绘图工坊Docker环境搭建与测试 1. 为什么选择SDXL 1.0与Docker组合 SDXL 1.0作为Stable Diffusion系列的最新升级版本&#xff0c;在图像生成质量上实现了质的飞跃。相比前代产品&#xff0c;它原生支持1024x1024高清分辨率&#xff0c;生…...