【面试题】马上金九银十了,简历该准备起来了,面试题你准备好了吗 ?浅谈 JS 浅拷贝和深拷贝

代码展示

let obj_old = {name: 'Tom',age: 15,favorite: {food: 'bread',drink: 'milk'}
}
let obj_new = {...obj_old}
console.log(obj_old === obj_new)  // false
console.log(obj_old.name === obj_new.name)  // true
console.log(obj_old.favorite === obj_new.favorite)  // true

3. Array.prototype.concat()

语法:arr.concat(value0, /* … ,*/ valueN)

注:如果省略了所有 valueN 参数,则 concat 会返回调用此方法的现存数组的一个浅拷贝。

代码展示

let arr_old = [1, 2, {name: 'Tom'}]
let arr_new = arr_old.concat()
console.log(arr_old === arr_new)  // false
console.log(arr_old.name === arr_new.name)  // true

4. Array.prototype.slice()

语法:arr.slice(begin, end)

注:如果省略了 beginend 参数,则 slice 会返回调用此方法的现存数组的一个浅拷贝。

代码展示

let arr_old = [1, 2, {name: 'Tom'}]
let arr_new = arr_old.slice()
console.log(arr_old === arr_new)  // false
console.log(arr_old.name === arr_new.name)  // true

🌄深拷贝

接下来说深拷贝

深拷贝就是在堆内存中开辟一个新的空间存放新对象,拷贝原对象的所有属性,拷贝前后两个对象互不影响

深拷贝的新旧对象不共享内存

这时我们去修改新对象中的任意层级的任意属性值,都不会对原对象产生影响,原对象依然保持不变

举个栗子🌰

let obj_old = {name: 'Tom',age: 15,hobby: ['eat', 'game'],favorite: {food: 'bread',drink: {dname: 'milk',color: 'white',},}
}
let obj_new = _.cloneDeep(obj_old)
console.log(obj_old)
console.log(obj_new)
console.log(obj_old.name === obj_new.name)
console.log(obj_old.favorite === obj_new.favorite)
console.log(obj_old.favorite.drink === obj_new.favorite.drink)

这里我们使用了lodash工具库提供的_.cloneDeep深拷贝方法,来看一下新旧对象的对比

可以看见新旧对象所有属性及属性值完全相同

那再来细节对比一下,看看拷贝后对象的地址是否相同

obj_old.name === obj_new.name为true,这个是基本数据类型,完全相同,没有问题

obj_old.favorite === obj_new.favorite,这里为false,到这里就和浅拷贝不同了,浅拷贝到这一层的时候,对象属性的地址是相同的,而深拷贝是完全拷贝出一个新的对象,所以不管是哪一层,对象属性的地址都是不同的

obj_old.favorite.drink === obj_new.favorite.drink为false,再往深一层仍然是false,即地址不相同

那再来修改一下属性值,看看前后对比

obj_new.name = 'Jerry'
obj_new.hobby[0] = 'sing'
obj_new.favorite.food = 'cheese'

修改属性值之后,新旧对象是互不影响的

🏷️深拷贝的方法

那么现在就来罗列几个深拷贝的方法

1. 递归实现

使用递归实现原对象每一层的拷贝,当遇到基本数据类型时,直接拷贝,遇到引用数据类型时,递归拷贝它的每个属性

代码展示

const obj_old = {name: 'Tom',age: 15,hobby: ['eat', 'game'],favorite: {food: 'bread',drink: {dname: 'milk',color: 'white',},}
}
const obj_new = {}function deepClone(newObj, oldObj){for (const key in oldObj) {if (oldObj[key] instanceof Object) {newObj[key] = {}deepClone(newObj[key], oldObj[key])} else if (oldObj[key] instanceof Array) {newObj[key] = []deepClone(newObj[key], oldObj[key])} else {newObj[key] = oldObj[key]}}
}deepClone(obj_new, obj_old)console.log(obj_old)
console.log(obj_new)
console.log(obj_old.name === obj_new.name)
console.log(obj_old.favorite === obj_new.favorite)
console.log(obj_old.favorite.drink === obj_new.favorite.drink)

测试结果

2. lodash工具包

点这里去lodash的中文文档

引入成功后,我们直接使用lodash提供给我们的函数_.cloneDeep就行

代码展示

let obj_old = {name: 'Tom',age: 15,hobby: ['eat', 'game'],favorite: {food: 'bread',drink: {dname: 'milk',color: 'white',},}
}
let obj_new = _.cloneDeep(obj_old)console.log(obj_old)
console.log(obj_new)
console.log(obj_old.name === obj_new.name)
console.log(obj_old.favorite === obj_new.favorite)
console.log(obj_old.favorite.drink === obj_new.favorite.drink)

测试结果

3. JSON.parse(JSON.stringify(obj))

JSON.stringify() 将JSON格式的对象转为字符串

JSON.parse() 将JSON格式的字符串转为对象

代码展示

const obj_old = {name: 'Tom',age: 15,hobby: ['eat', 'game'],favorite: {food: 'bread',drink: {dname: 'milk',color: 'white',},}
}
const obj_new = JSON.parse(JSON.stringify(obj_old))console.log(obj_old)
console.log(obj_new)
console.log(obj_old.name === obj_new.name)
console.log(obj_old.favorite === obj_new.favorite)
console.log(obj_old.favorite.drink === obj_new.favorite.drink)

测试结果

❣️虽然这个方法最简单,代码行数最少,但是它也有一定的缺陷:

  1. 拷贝对象的值中如果有‘函数’,‘undefined’,‘symbol’ JSON.stringify()序列化后,键值对丢失
  2. 拷贝RegExp会变成空对象{}
  3. 对象中含有‘NaN’,‘Infinity’会变成null
  4. 拷贝Date会变成字符串

🏝️结语

其实前端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

这里再分享一个复习的路线:(以下体系的复习资料是我从各路大佬收集整理好的)

《前端开发四大模块核心知识笔记》

最后,说个题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/34407.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis源码学习:SDS设计与内存管理

为什么Redis选择SDS 1、缓解C语言字符串的缺陷 在 C 语言中可以使用 char* 字符数组来实现字符串。每个字符串分配一段连续的内存空间,依次存放字符串中的每一个字符,最后以null字符结尾。这种设计存在以下问题: 1、低效的操作 每次获取字…

Linux根目录挂载点(/dev/mapper/centos-root)扩容

如果我们在安装系统是采用自定义分区的话,就可以提前规划好这个事情。但是如果平常没注意就直接采用默认安装的方式的话。一旦 根目录的容量耗尽,将会影响业务的运行。今天我们来扩容逻辑卷。 默认安装的话会给home目录分比较多的空间,我们可…

【Leetcode每日一题】 01背包 - DP41 【模板】01背包(难度⭐⭐)(80)

1. 题目解析 题目链接:DP41 【模板】01背包 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 第一问:不超过总体积的背包问题 1. 状态表示 dp[i][j] 表示:从前 i 个物品中挑选&…

汇编语言实验八

目录 一、实验目的 二、实验内容 三.实验步骤以及结果 1、阅读monthtab.asm 程序,要求写出该程序功能,并在实验报告中画出其程序流程图 2.编写一段程序,要求在长度为20的数组(无符号数)中,…

LabVIEW与C#相互调用dll

C#调用LabVIEW创建的dll 我先讲LabVIEW创建自己的.net类库的方法吧,重点是创建,C#调用的步骤,大家可能都很熟悉了。 1、创建LabVIEW项目,并创建一个简单的add.vi,内容就是abc,各个接线端都正确连接就好。 …

云层之间穿梭特效视频转场PR模板素材

12 个超赞的 Premiere Pro 云层穿梭特效视频转场模板 https://prmuban.com/39056.html 📽 你是否正在寻找一种方法,让你的视频更酷、更时尚、更吸引人?今天推荐的12个逼真的云层穿梭特效视频转场模板,绝对能为你的作品锦上添花 ✨…

智赢选品,OZON数据分析选品利器丨萌啦OZON数据

在电商行业的激烈竞争中,如何快速准确地把握市场动态、洞察消费者需求、实现精准选品,是每个电商卖家都面临的挑战。而在这个数据驱动的时代,一款强大的数据分析工具无疑是电商卖家们的得力助手。今天,我们就来聊聊这样一款选品利…

我也认为说 360 无法卸载这一说法,是一个 “彻头彻尾的谣言”

最近,360 公司董事长周鸿祎发布视频回应了 360 无法卸载这一说法,称其是一个 “彻头彻尾的谣言”。他解释道,360 软件完全可以卸载,在设置里面有卸载的入口,通过软件管家也可以正常卸载。不能卸载的说法完全是断章取义…

【UIDynamic-动力学-UIPushBehavior-推行为 Objective-C语言】

一、接下来,我们来说这个,推行为, 1.推行为,首先,它叫做UIPushBehavior, 这个里边呢,又分为持续推力、瞬时推力, 我们新建一个项目,叫做:13-推行为 我们这个里边,还是先来一个redView, UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(100,100,…

【开发】利用SSH端口转发通过阿里云服务器访问实验室设备

文章目录 写在前面公网服务器与实验室服务器连通性公网服务器ping实验室实验室ping公网服务器SSH隧道转发 写在前面 最近实验室搬家,导致无法访问内网,之前搭建的zerotier组网成功利用手机热点访问,但是无奈zerotier的不稳定导致开发效率低&…

B端产品竞品分析-总结版

B端竞品分析的难点 分析维度-业务逻辑复杂 B端产品与C端产品业务模型不同,B端产品主要以业务为导向,因此其业务流程与业务逻辑梳理起来也会较C端产品复杂的多,对于个人能力也有一定的要求,需要我们具备相关领域或行业专业知识。…

猫头虎分享已解决Bug:Array Index Out of Bounds Exception

🐯 猫头虎分享已解决Bug:Array Index Out of Bounds Exception 🐯 摘要 大家好,我是猫头虎,今天我们要聊聊后端开发中经常遇到的一个问题:Array Index Out of Bounds Exception,即 java.lang.…

win10 修改远程桌面端口,在Win10上修改远程桌面端口的要怎么操作

在Windows 10上修改远程桌面端口是一个涉及系统配置的过程,这通常是为了增强安全性或满足特定网络环境的需要。 一、通过注册表编辑器修改远程桌面端口 1. 打开注册表编辑器: - 按下Win R组合键,打开“运行”对话框。 - 在“运行”对话框…

大模型揭秘:AI与CatGPT在实体识别中的创新应用

摘要 尽管大规模语言模型 (LLM) 在各种 NLP 任务上已经取得了 SOTA 性能,但它在 NER 上的性能仍然明显低于监督基线。这是由于 NER 和 LLMs 这两个任务之间的差距:前者本质上是序列标记任务,而后者是文本生成模型。在本文中,我们…

【大数据】—双均线策略(移动平均线)

声明:股市有风险,投资需谨慎!本人没有系统学过金融知识,对股票有敬畏之心没有踏入其大门,今天用另外一种方法模拟炒股,后面的模拟的实战全部用同样的数据,最后比较哪种方法赚的钱多。 量化交易…

《2024云安全资源池 能力指南》

《2024云安全资源池 能力指南》这份报告不仅梳理了云安全资源池的发展历程,还深入探讨了其在当前云计算环境下的重要性和必要性。报告详细分析了云安全资源池的市场需求、技术架构、关键技术以及行业应用案例,为政企用户提供了全面的云安全解决方案。通过资料收集、问卷调研、企…

Unity | Shader基础知识(番外:模型的制作流程)

目录 一、前言 二、模型的诞生 三、模型的表面 四、模型的贴图 五、上完材质的模型 六、材质的来源 七、作者的碎碎念 一、前言 up发现,初学程序,除非你是美术,模型出生,要不然对这些都是萌萌哒(蒙蒙哒&#x…

从宏基因组中鉴定病毒序列(2)

Introduction 在环境微生物学和生态学研究中,宏基因组学(Metagenomics)技术的应用已经彻底改变了我们对微生物群落的理解。宏基因组学通过对环境样本中的全部遗传物质进行测序和分析,可以全面揭示微生物群落的组成、功能和相互作…

Modbus转Profibus网关在汽车行业的应用

一、前言 在当前汽车工业的快速发展中,汽车制造商正通过自动化技术实现生产的自动化,目的是提高生产效率和减少成本。Modbus转Profibus网关(XD-MDPB100)应用于汽车行业,主要体现在提升自动化水平、优化数据传输以及实…

刷题之小欧的平均数(卡码网)

小欧的平均数 这道题不看解析的话完全没有思路&#xff0c;连题目都没读明白&#xff0c;甚至看了评论答出来了还是不知道为什么&#xff0c;有知道的朋友可以教教我 #include<iostream> using namespace std;int main() {int x,y,z;cin>>x>>y>>z;//…