面试题:说一说深拷贝和浅拷贝?

本文详细介绍了JavaScript中基本类型和引用类型的区别,以及浅拷贝(如Object.assign和扩展运算符)和深拷贝(递归、lodash的cloneDeep和JSON.stringify)的概念。重点讨论了浅拷贝的局限性和深拷贝的实现方法及其弊端。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaScript中存在两大数据类型: 基本类型 和 引用类型

基本类型数据保存在在栈内存中
引用类型数据保存在堆内存中,引用数据类型的变量是一个指向堆内存中实际对象的引用,存在栈中

深拷贝和浅拷贝都只针对于引用类型。

一、 浅拷贝:拷贝的是地址。如下就是一个浅拷贝的方法:

1、拓展运算符

在这里插入图片描述

先了解一下Object.assign方法,如下图所示:

在这里插入图片描述

简单对象用Object.assign()方法实现浅拷贝如下:这是es6新增的。

2、Object.assign()

在这里插入图片描述

总结:浅拷贝只拷贝一层简单数据类型(即,简单数据类型只会拷贝值),但是对于更深层次的对象,只会拷贝它的地址。

简单理解:浅拷贝,如果拷贝的是单层对象,就没问题,如果有多层就有问题。

问题1:直接赋值和浅拷贝有什么区别?

答:直接赋值的方法,只要是对象,都会相互影响,因为是直接拷贝对象栈里面的地址。

浅拷贝如果是一层对象,不相互影响,如果出现多层对象拷贝还会相互影响。

问题2:浅拷贝怎么理解?

答:拷贝对象之后,里面的属性值是简单数据类型直接拷贝值。

如果属性值是引用数据类型则拷贝的是地址。

二、深拷贝:拷贝的是对象,不是地址

常见方法:1、通过递归实现深拷贝;2、lodash/cloneDeep;3、通过JSON.stringify()实现

1、递归深拷贝(简易版)

在这里插入图片描述

先理解一下下面这段代码:这个代码只解决了数组的问题,但是没解决对象的问题。

在这里插入图片描述
在这里插入图片描述

再加上下面这段代码,就能解决数组和对象的问题了

在这里插入图片描述

注意:一定要先把数组写在前面,因为数组也属于对象形式,万物皆对象,即:先筛选完数组之后,再筛选对象。

问:做过深拷贝吗?说一下深拷贝是怎么实现的。

答:做过,深拷贝啊做出来对象,新对象不会影响旧对象,要想实现深拷贝,第一啊,深拷贝要用到函数递归,当我们在普通拷贝的时候没问题,直接进行赋值就行了;但是如果遇到数组的,我们再次调用这个递归函数就可以了;如果遇到的是对象形式,那我再次利用递归,把对象解决;但是一定要先递归数组,再递归对象。

2、js库lodash里面cloneDeep内部实现了深拷贝。

官网解释如下:

在这里插入图片描述

代码如下:

在这里插入图片描述

JSON对象的Stringify和Parse来实现深拷贝。要了解弊端

理解:类似于阳澄湖大闸蟹,把其他的螃蟹拿进阳澄湖里涮一涮,再拿出来,就成了阳澄湖大闸蟹,表面看起来一样,其实完全不一样。

在这里插入图片描述

该方法的弊端:

1、obj里面有new Date(),深拷贝后,时间会变成字符串的形式。而不是时间对象;
2、obj里有function,undefined,则序列化的结果会把function或 undefined丢失;
3、obj里有NaN,则序列化的结果会变成null;
4、JSON.stringify()只能序列化对象的可枚举的自有属性,如果obj中的对象是由构造函数生成的实例对象, 深拷贝后,会丢弃对象的constructor;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值