js 简析深拷贝和浅拷贝

187 阅读2分钟

1)深拷贝和浅拷贝的起因

认识堆栈
堆栈是计算机最基本的数据排序的数据结构,在储存数据的时候,堆栈有着自己的储存方式,可以自己单独储存数据,可以相互配合使用。栈的储存空间比较小,所以他能储存一下比较简单的数据格式,比如js命名的(undefined,boolean,number,string,null)五种简单类型,堆的内存比较大,所以可以储存数据比较大的格式,比如对象(数组也是特殊的对象),在堆栈配合使用时,栈中会储存一个属性和一个指针,堆中会储存这个属性的属性值,属性和属性值的对应由指针完成,所以在拷贝的过程中是进行了完全拷贝,还是只拷贝了指针,从而产生了深拷贝和浅拷贝
深拷贝和浅拷贝的区别
通俗话讲,就是命名一个属性,同时给这个属性一个值,然后你把这个属性赋值给另一个其他的属性,那么另一个命名的属性就有了之前的那个属性值,在你改变其中一个属性的属性值的时候,另一个属性的属性值会不会随之改变,改变了就为浅拷贝,没改变为深拷贝

2)深拷贝和浅拷贝的形成过程

说完了堆栈的计算机数据结构,接下来分析js整个拷贝过程
现在说
深拷贝(简单类型)

var a = 1
var b = a
//修改b的值
    b = 3
    console.log('a的值====>>>>', a)
    console.log('a的值====>>>>', b)
    //打印结果 a: 1 ; b: 3

图分析

可以简单看出,在栈中存储数据进行拷贝的时候是把属性和属性值都进行了copy,同时指针也是各自的对应,所以你对b(或者a)进行修改的时候各自都不会受到影响
浅拷贝(复杂类型)

var a = [1,2,3,4,5]
var b = a
//修改b的值
    b.push(0)
    console.log('a的值====>>>>', a)
    console.log('a的值====>>>>', b)
    //打印结果 a: [1,2,3,4,5,0] ; b: [1.2.3.4.5,0]

图分析

这个可以看出,复杂类型在拷贝的时候是把属性和指针进行了copy 但是指针对应的只是堆中的一个数组,当你对一个属性中的值进行修改的时候,那么另一个属性的属性值也会改变,因为这个属性对应的只是堆中的一个值

3)解决浅拷贝的办法

数组的解决办法:

  • 1.for循环
  • 2.slice(0)截取
  • 3.Array.from()
  • 4.扩展运算符
  • 5.concat运算

对象的解决办法:

  • 1.JSON.stringfy()转换成字符串,再利用JSON.parse()再转换回来
  • 2.for循环
  • 3.扩展运算符
  • 4.ES6新算法Object.assign()
    方法4使用时要注意***使用方法