JS面试题-<变量和类型>-JavaScript浅拷贝与深拷贝
前言
最开始了解到深浅拷贝是因为准备面试,但那个时候因为在学校做的项目比较少需求也比较简单,所以没有在项目中遇到这类问题,所以对这个问题就属于知道这个知识点,看过相关内容,却没有自己的总结,也没有深入的了解。后来在工作中遇到过两次这样的问题,第一次遇到后我写了一篇文章《在vue项目中遇到关于对象的深浅拷贝问题(地址指向)》https://www.cnblogs.com/songForU/p/11187861.html,记录了需求、错误代码及解决方案,那个时候认为自己的解决方案就是深拷贝;然而第二次遇到问题后,无论我怎么使用那些方案都无法解决问题,也写了一篇文章记录了一下解决方案,《javascript数组/对象数组的深浅拷贝问题》https://www.cnblogs.com/songForU/p/11469498.html,但是很遗憾我依旧没有搞明白之前我认为的“深拷贝”为什么出现了问题,可笑的是依旧没有去深入了解,只是简单的记住了解决方案。
直到最近我组长给我一个截图,上面是关于深浅拷贝的知识点。我看了内容就懵了,为啥我之前认为“深拷贝”方法是浅拷贝,那到底什么是深浅拷贝?截图内容大致如下:
浅拷贝
拷贝属性值到新的对象中,如果属性是对象的话拷贝的是地址,对象属性指向共同的地址;其中Object.assign()和...可以实现浅拷贝。
深拷贝
拷贝属性值到新的对象中;两个对象没有任何关系;可以通过JSON.parse(JSON.stringify(object))进行大多数的拷贝,;这个方法有一定的局限性,如下:
1、会忽略undefined
2、会忽略symbol
3、不能序列化函数
4、不能解决循环引用的对象
一、浅拷贝
问:什么是浅拷贝?
涉及到深浅拷贝则是关于对象的复制,但是并不是所有的复制操作都叫做浅拷贝。现在我的理解是,我们对引用类型进行复制想要的结果无非是,两个变量互不影响即可,也就是所谓的深拷贝。当你在进行对象复制的时候,只要保证了复制后的对象和被复制的对象的内存地址是两个完全不同地址,则便达到了“深拷贝”,可能你这种方法并不适用于所有对象,有局限性罢了,但是确实是达到了效果。
我之前对深浅拷贝产生误解就是由于自己认为的那些完成了“深拷贝”的方法不适用与所有对象罢了,特别是那些有嵌套对象关系的。
1)Object.assign()、展开运算符...、Array.prototype.slice()、concat等真的不能达到“深拷贝”的效果么?
凡事都有例外,想找到一个普世通用的理论或方法,总那么不尽人意,但总能解决一部分的问题。
像下面这种没有嵌套关系的对象、数组,即第一层为基本数据类型的,使用上面的几个方法都可以达到“深拷贝”的效果,去改变复制后的数据不会使原数据同一改变,因为此时两者的内存地址也是不同的。
let obj = {
name:"song",
age:1
}
let arr = ["1","2","3"];
但是对于复杂的数组,嵌套的对象则不适用,即第一层不是基本数据类型而是引用数据类型;使用上述方法后在改变数据包含的对象则会使原数据一同改变。
let obj = {
name:"song",
age:1,
job:{
price:10,
work:"eng"
}
}
let arr = ["1","2",[2,3]];
let arr = ["1","2",{name:"s",age:1}];
当然也不是说,只要是复杂嵌套的对象就一定不能使用上述方法来达到”深拷贝“的效果。如果在开发项目中,你知道数据的结构便可以对数据二次遍历操作,从而达到"深拷贝"的效果。就比如我之前做的项目中的使用方法。
dataList.map(o => ({...o}));
2)深拷贝
所谓的深拷贝就是会拷贝所有的属性后,操作任意一个,两者互不影响,无论是几层嵌套都能够各自独立。
一般来说比较简单的方法是利用JSON.parse(JSON.stringify(object)),但该方法也存在一些问题,只不过比刚才浅拷贝的几种方法,解决拷贝问题的通用性更高一些罢了。
当对象里面包含有以下内容,哪怕是一层结构也会有问题。
1、会忽略
undefined2、会忽略
symbol3、不能序列化函数
4、不能解决循环引用的对象
示例如下:
let obj = {
name:"song",
va:undefined,
vb:Symbol('song'),
vc:function () {}
}
console .log(obj);
let a = JSON.parse(JSON.stringify(obj));
console.log(a);

3)怎么样实现一个深拷贝?
(暂未整理)
JS面试题-<变量和类型>-JavaScript浅拷贝与深拷贝的更多相关文章
- JS面试题-<变量和类型>-JavaScript的数据类型
前言 整理以前的面试题,发现问js数据类型的频率挺高的,回忆当初自己的答案,就是简简单单的把几个类型名称罗列了出来,便没有了任何下文.其实这一个知识点下可以牵涉发散出很多的知识点,如果一个面试者只是罗 ...
- Python中变量、赋值、浅拷贝、深拷贝
https://www.cnblogs.com/LetMe/p/6724555.html 在理解浅拷贝和深拷贝之前,首先要理解学习一下变量在Python中是怎样存储的: 变量的类型是分值引用与地址引用 ...
- Javascript 浅拷贝与深拷贝
在了解JS的浅拷贝与深拷贝之前,我们需要先知道什么是值传递与引用传递. 在JS中,基本类型值的拷贝是按值传递的,而引用类型值的拷贝则是按引用传递的.通过值传递的变量间不会有任何牵连,互相独立:但是引用 ...
- 浅谈Javascript 浅拷贝和深拷贝的理解
javascript中存储对象都是存地址的. 浅拷贝:浅拷贝是都指向同一块内存区块,浅拷贝共用同一内存地址,你改值我也变.如果拷贝的对象里面的值是一个对象或者数组,它就是浅拷贝,拷贝的知识引用地址. ...
- javascript浅拷贝和深拷贝
/* 浅拷贝 */ function extend(parent, child) { var i; child = child || {}; for (i in parent) { if (paren ...
- JS的引入方式_变量的使用_变量的类型
JS的俩种引入方式: 1. <!--js的引入方式1--> <script> /*网页中的弹框*/ alert("js的学习!!") </script ...
- Python中的可变对象与不可变对象、浅拷贝与深拷贝
Python中的对象分为可变与不可变,有必要了解一下,这会影响到python对象的赋值与拷贝.而拷贝也有深浅之别. 不可变对象 简单说就是某个对象存放在内存中,这块内存中的值是不能改变的,变量指向这块 ...
- JavaScript基础系列(变量与类型)
以下内容将JavaScript简称为JS 打开本文时不管你是零基础的初学者还是其他语言的老兵,我都想说程序语言的基础支撑起了整个网络世界,不把这些基础学透之后稍复杂的内容会让你寸步难行. 现在先给编程 ...
- JavaScript学习笔记——JS中的变量复制、参数传递和作用域链
今天在看书的过程中,又发现了自己目前对Javascript存在的一个知识模糊点:JS的作用域链,所以就通过查资料看书对作用域链相关的内容进行了学习.今天学习笔记主要有这样几个关键字:变量.参数传递.执 ...
随机推荐
- LeetCode初级算法--数组02:旋转数组
LeetCode初级算法--数组02:旋转数组 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/ ...
- .net core 3.0 WPF中使用FolderBrowserDialog
前言 随着.net core 3.0 的发布,WPF 也可以在 core 平台上使用了.当前的 WPF 不支持跨平台,仅能够在 Windows 平台上使用.如果想体验 WPF 跨平台开发,可以访问开源 ...
- HeidiSQL、Navicat、mysql命令和source命令导入sql脚本的速度比较
一.四种导入方式的比较 1.heidisql客户端是一条一条插入的,速度最慢,而且很脆弱比较容易崩溃: 2.mysql命令导入380万记录用时1小时13分(属于前台运行的命令,ctrl+c就可以结束) ...
- 苹果开始推送 macOS Catalina10.15 正式版系统更新
北京时间今天凌晨 1 点,苹果正式推送了 macOS Catalina 10.15 正式版升级.macOS Catalina 10.15 正式版带来了许多重大改变,包括Sidecar.iTunes应用 ...
- XGBoost: 你不能不知的机器学习算法
XGBoost作为一个非常常用的算法,我觉得很有必要了解一下它的来龙去脉,于是抽空找了一些资料,主要包括陈天奇大佬的论文以及演讲PPT,以及网络上的一些博客文章,今天在这里对这些知识点进行整理归纳,论 ...
- [网络流 24 题] luoguP2763 试题库问题
[返回网络流 24 题索引] 题目描述 假设一个试题库中有 nnn 道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取 mmm 道题组成试卷.并要求试卷包含指定类型的试题. ...
- [JZOJ5817] 【NOIP提高A组模拟2018.8.15】 抄代码
Description J 君是机房的红太阳,每次模拟她总是 AK 虐场.然而在 NOIP2117 中,居然出现了另一位 AK 的选手 C 君! 这引起了组委会的怀疑,组委会认为 C 君有抄袭 J 君 ...
- php反序列化漏洞复现过程
PHP反序列化漏洞复现 测试代码 我们运行以上代码文件,来证明函数被调用: 应为没有创建对象,所以构造函数__construct()不会被调用,但是__wakeup()跟__destruct()函数都 ...
- Spring入门(五):Spring中bean的作用域
1. Spring中bean的多种作用域 在默认情况下,Spring应用上下文中所有的bean都是以单例(singleton)的形式创建的,即不管给定的一个bean被注入到其他bean多少次,每次所注 ...
- Service Mesh 初体验
前言 计算机软件技术发展到现在,软件架构的演进无不朝着让开发者能够更加轻松快捷地构建大型复杂应用的方向发展.容器技术最初是为了解决运行环境的不一致问题而产生的,随着不断地发展,围绕容器技术衍生出来越来 ...