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 个值分别是:
true和false。 - null,一个表明 null 值的特殊关键字。JavaScript 是大小写敏感的,因此
null与Null、NULL或变体完全不同。 - undefined,和 null 一样是一个特殊的关键字,undefined 表示变量未赋值时的属性。
- 数字(Number),整数或浮点数,例如:
42或者3.14159。 - 任意精度的整数(BigInt),可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。
- 字符串(String),字符串是一串表示文本值的字符序列,例如:
"Howdy"。 - 代表(Symbol,在 ECMAScript 6 中新添加的类型)。一种实例是唯一且不可改变的数据类型。
- 布尔值(Boolean),有 2 个值分别是:
- 基础数据类型的值均存储在栈中,每个值都有一个独立的内存空间,在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
分析
- 引用类型(数组)
- 一般情况下引用类型的值会作为数据的有序或无序集合即一个数组中包含着许多的数据,通常他们的数据体量都较为庞大,所以一般引用类型的数据都存放在堆内存中,并且在栈内存中开辟一个地址单元指向其堆内存中的地址
- 在数组进行复制的时候,本质上复制的是数组在堆内存中的地址,也就是 team和players这两个变量指向的是同一个数组,那么当其中一个对其进行改变的时候,另一个也会受到一定的影响
- 那么如何解决这个问题?
- 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的原理及使用 官网地址:…...
对象变更记录objectlog工具(持续跟新)
文章目录 前言演示代码演示环境引入项目项目框架操作步骤 设计介绍参考仓库 前言 系统基于mybatis-plus, springboot环境 对于重要的一些数据,我们需要记录一条记录的所有版本变化过程,做到持续追踪,为后续问题追踪提供思路。下面展示预期效果…...
平衡二叉树,二叉树的路径,左叶子之和
第六章 二叉树part04 今日内容: 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和 110.平衡二叉树 (优先掌握递归) 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为&am…...
Sodinokibi勒索病毒最新变种,解密工具更新到2.0版本
Sodinokibi勒索病毒 Sodinokibi勒索病毒又称REvil,自从2019年6月1日,GandCrab勒索病毒运营团伙宣布停止运营之后,Sodinokibi勒索病毒马上接管了GandCrab的大部分传播渠道,同时它也被称为是GandCrab勒索病毒的“接班人”ÿ…...
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(朴素数据并行,Zero数据并行之后补充) O ( h 2 ∗ l ) O(h^2*l) O(h2∗l) 每台机器做完自己的梯度后需要做一次All reduce操作来累积梯度,故一个batch计算发送的数据量为每层梯度大小 h 2 h^2 h2乘以层数 l l l 优点…...
PMP考试之20240304
1.一家食品公司正在使用预测型方法开发一种新产品,该产品目前正处于测试阶段。鉴于测试反馈的性质,项目经理决定使用迭代方法。在其中一个迭代结束时,颁布了与该产品有关的新法规。项目经理接下来应该做什么? A.就项目的范围提出…...
智慧城市中的公共服务创新:让城市生活更便捷
目录 一、引言 二、智慧城市公共服务创新的实践 1、智慧交通系统 2、智慧医疗服务 3、智慧教育系统 4、智慧能源管理 三、智慧城市公共服务创新的挑战 四、智慧城市公共服务创新的前景 五、结论 一、引言 随着信息技术的迅猛发展,智慧城市已成为现代城市发…...
bert 相似度任务训练完整版
任务 之前写了一个相似度任务的版本:bert 相似度任务训练简单版本,faiss 寻找相似 topk-CSDN博客 相似度用的是 0,1,相当于分类任务,现在我们相似度有评分,不再是 0,1 了,分数为 0-5,数字越大…...
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)
在上一篇(【UE 材质】制作加载图案)基础上继续实现如下效果的加载图案 效果 步骤 1. 复制一份上一篇制作的材质并打开 2. 添加“Floor”节点向下取整 除相同的平铺数 此时的效果如下 删除如下节点 通过“Ceil”向上取整,参数“Tiling”默认…...
为啥要用C艹不用C?
在很多时候,有人会有这样的疑问 ——为什么要用C?C相对于C优势是什么? 最近两年一直在做Linux应用,能明显的感受到C带来到帮助以及快感 之前,我在文章里面提到环形队列 C语言,环形队列 环形队列到底是怎么回…...
Java:JVM基础
文章目录 参考JVM内存区域程序计数器虚拟机栈本地方法栈堆方法区符号引用与直接引用运行时常量池字符串常量池直接内存 参考 JavaGuide JVM内存区域 程序计数器 程序计数器是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器,各线程…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
