通俗易懂解释javaScript中深拷贝和浅拷贝(有图有真相)
简单来讲,浅拷贝就只是复制了一层,也就是拷贝对象共用源对象的堆内存地址,
而深拷贝就是复制多层,就是把源对象里面的属性也复制给新对象自己一遍,创建了自己的新堆内存地址。
上面的话没看懂没关系,看下面的图
如下图就是浅拷贝
person是一个源对象,person源对象中有一个属性,属性名叫做dog,该dog也是一个对象(即person源对象中嵌套了一个dog对象)
浅拷贝就只是复制了一层,这句话怎么理解呢?
- 看上图就明白了,copyPerson对象是拷贝对象,该copyPerson对象是通过拷贝person源对象后得到的对象;
- 在拷贝person源对象的过程中,如果遇到name,age这种基本数据类型,就直接拷贝;
- 如果遇到dog这种引用数据类型就拷贝dog的内存地址,换言之,就是拷贝dog的内存地址,而不会继续拷贝dog对象里面的hobby属性和address属性了;
- 所以,大家从上图中可以看出,person的dog和copyPerson的dog是指向同一块内存空间(即copyPerson.dog.hobby = "吃狗粮"这句话,也会影响到person源对象的dog的hobby)。
- 可以使用console.log(copyPerson.dog == person.dog);这句话,打印出来看一下,看看copyPerson.dog和person.dog是否指向同一块内存地址。
- 以上就是浅拷贝的现象。
如下图就是深拷贝
深拷贝就是复制多层,就是把源对象里面的属性也复制给新对象自己一遍,创建了自己的新堆内存地址。这句话怎么理解呢?看下图:
- 看上图就明白了,copyPerson对象是拷贝对象,该copyPerson对象是通过拷贝person源对象后得到的对象;
- 在拷贝person源对象的过程中,如果遇到name,age这种基本数据类型,就直接拷贝;
- 如果遇到dog这种引用数据类型就会继续进入dog的内部去获取hobby和address属性;
- 在拷贝person源对象的过程中,如果遇到dog这种引用数据类型,那么copyPerson对象就会创建一个dog变量,并且指向新的内存空间,大概过程是:copyPerson.dog = {};//此时copyPerson.dog指向了一块新的内存空间
- 然后copyPerson.dog.hobby = person.dog.hobby; copyPerson.dog.address= person.dog.address;(即拷贝时,如果遇到dog这种引用数据类型时,会深入到dog内部去拷贝,说白了就是一级一级的拷贝,拷贝到底的意思,其实就是类似于递归)
- 大家可以把深拷贝理解成递归拷贝,就是递归。
- 可以使用console.log(copyPerson.dog == person.dog);这句话,打印出来看一下,看看copyPerson.dog和person.dog是否指向同一块内存地址。
- copyPerson.dog和person.dog不是指向同一块内存空间,所以,copyPerson.dog.hobby = "吃狗不理包子"这句话,不会影响到person源对象的dog的hobby
- 以上就是深拷贝的现象。