一文看懂:JS深拷贝与浅拷贝

351 阅读2分钟

我们先来说一下浅拷贝:

carbon (3).png

这就是浅拷贝

但是浅拷贝会存在一个问题,我们上面通过浅拷贝拷贝了一个引用类型,如果我们去修改obj会怎么样?

carbon (4).png

我们会发现通过浅拷贝一个引用类型,如果修改obj,最终b也会跟着修改,是因为在拷贝的时候,我们只是将引用地址拷贝给了b,也就是说bobj引用的是同一个对象

所以我们代码就要改良一下,需要将obj里面的元素取出来然后交给b

carbon (5).png

这样就完美的解决了问题哈哈哈

但是我们作为一个好的程序员,要去发现问题,再来看下一个问题,如果obj里面又包含了一个c对象,然后修改c会怎么样

carbon (6).png

当我们修改了obj里面的c对象的时候,b里面的c也跟着变化了,原因就是,b里面拷贝的c也是一个引用类型,从而拷贝的只是一个地址,并且还有一个问题,就是我们不知道obj里面有多少层,可能c1里面又包含一个引用类型,并且我们不知道引用类型是对象还是数组,那么我们就要解决这个问题,这样的问题就是深拷贝。

61F347F3D384CAD0949D2B4AC6D7363C.jpg

我们可以先利用一个简单方式来实现深拷贝

carbon (7).png 我们先将需要拷贝的代码利用JSON.stringify转成字符转,然后再利用 JSON.parse将字符转转回对象,即完成拷贝

但是有的面试官会问你,能够利用递归实现吗?回答当然可以

我们就再利用递归来实现深拷贝

递归实现的思路是什么样的?我们来分析一下

  • 我们肯定要定义一个方法,那么这个方法最终应该返回一个深拷贝的数据
  • 既然要返回一个数据,我们首先就要定义一个数据,但是数据是对象还是数组?所以需要判断,如果要拷贝的数据是数组,即定义一个数组,如果是一个对象,即定义一个对象
  • 方法里面怎么拷贝啊?还是一样的利用for in 循环,在循环内部,需要判断,如果是类型是简单类型,直接拷贝,如果是引用类型,就需要在一次的将引用类型里面的值取出来 根据上面的逻辑我们处理一下代码

carbon (8).png 至此一个深拷贝就完成了~~~