【修真院web小课堂】 如何实现数组深拷贝和浅拷贝

【修真院web小课堂】 如何实现数组深拷贝和浅拷贝

大家好,我是IT修真院西安分院第1期的学员,一枚正直纯洁善良的WEB程序员

1.知识剖析

js有深拷贝和浅拷贝的区别,

js中的两种变量类型, 即值类型(数值、布尔值、null、undefined) 和引用类型(对象、数组、函数)。值类型保存于栈中,而引用类型保存在堆中。值类型和引用类型赋值时的不同, 值类型赋值时会在内存中开辟一块新的空间,然后把赋过来的值保存于这块新开辟的空间中,引用类型赋值时也会开辟一块新的空间,不同的时新的空间保存的是赋值对象虽在的地址(即浅拷贝,也就是说赋值和被赋值对象引用的是同一个对象,所以改变其中任何一个对象时,另一个会随之改变)。所以深拷贝和浅拷贝概念只针对于引用类型,对于值类型来说没有意义。

复制的时候相当于复制引用地址

浅拷贝:相当于使两个数组指针指向相同的地址,任一个数组元素发生改变, 影响另一个。

深拷贝:两数组指针指向不同的地址,数组元素发生改变时不会相互影响。


2.常见问题

3.解决问题

浅拷贝:





深拷贝:



除了js 里面的slice(), concat() ,  以及jq里面的extend()都可以实现深拷贝

jQuery.extend([deep], target, object1, object2, object3...),

 [deep]:默认false【不能显式设置为false;值为true时深度合并对象。

 target:其他对象复制到该对象

object:被合并的对象


arrayObject.slice(start,end)

tart 必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。

end 可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。


concat() 

rrayObject.concat(arrayX,arrayX,......,arrayX)

arrayX 必需。该参数可以是具体的值,也可以是数组对象。可以是任意多个。


二维数组

浅拷贝




深拷贝





如果对象obj

拷贝情况


 浅拷贝:只拷贝对象的第一层属性,对于属性中包含的属性不会复制;
 由于JavaScript对象均以地址的方式存贮,
 所以浅复制导致多个对象的属性均指向同一块地址。

深拷贝:对对象的每一层属性进行递归复制,

深层次的属性也不会指向同一块地址【同一个对象】。


    运行结果:由于对象的浅拷贝只复制第一层属性,
     因此obj b第一层属性的改变不会影响复制源,
     而第二层属性仍指向同一块地址,
     因此obj b的dance属性的today属性作改变之后,

     同一块地址处的obj a的dance属性的today属性同时变化了。

浅拷贝



深拷贝




4.解决问题

5.编码实战

6.扩展思考

7.参考文献

参考一:http://larry850806.github.io/2016/09/20/shallow-vs-deep-copy/

 [Javascript] 關於 JS 中的淺拷貝和深拷貝

参考二:http://jerryzou.com/posts/dive-into-deep-clone-in-javascript/

深入剖析JavaScript 的深复制



问题1:

什么叫深拷贝 浅拷贝?

答:浅拷贝:相当于使两个数组指针指向相同的地址,任一个数组元素发生改变,  影响另一个。

深拷贝:两数组指针指向不同的地址,数组元素发生改变时不会相互影响。

问题2:

除了递归,我们还可以借用JSON对象的parse和stringify?




问题3:

深拷贝和浅拷贝的区别?

答:浅复制 —-只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”,换句话说,浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变。
深复制 —-在计算机中开辟了一块新的内存地址用于存放复制的对象。



猜你喜欢

转载自blog.csdn.net/fgwas100/article/details/80256794