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

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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值