对象和数组的深度拷贝

115 阅读2分钟

1.我们都知道object和array是地址引用,有时我们会被一些表面所蒙蔽

(1) 例如下面的例子
const arr1 = [1,2,3]
const arr2 = [1,2,3]
console.log(arr1 === arr2)  //此时返回的是false

arr1和arr2这两个变量存的只是[1,2,3]这个数组在堆区的地址值,上面代码[1,2,3]是两块在堆区中独立的不同的内存区,所以他们所在内存区的地址值是不同的。而arr1和arr2存的就是他们在堆区中分别的地址值,所以这两个变量相比较,返回的就是false。

(2) 数组的赋值
 const arr1 = [1,2,3]
 const arr2 =arr1
 console.log(arr1 === arr2)  //此时返回的是true
 arr2[0] = 6
 console.log(arr1) // [6,2,3]

arr1赋值给arr2,此时只是赋值的是arr1对应的地址值,这样 arr1 和 arr2指向的是同一块的堆区内存,所以arr2对这块内存区操作,arr1也会跟着变化。

(2) 数组的深度拷贝
//一维数组
 const arr1 = [1,2,3]
 const [...arr2] = arr1
 const arr3 = arr1.slice(0)
 const arr4 = arr1.concat([])
 console.log(arr1 === arr2)  //false
 console.log(arr1 === arr3)  //false
 console.log(arr1 === arr4)  //false
 
 //多维数组
 const arr1 = [1,[2,3],4]
 const [...arr2] = arr1
 console.log(arr1 === arr2)  //false
 console.log(arr1[1] === arr2[2])  //true
 //由此可见上面拷贝的还是不够彻底 arr1和arr2 虽然独立了,但是arr1[1]和arr[2]元素还是指向了同一个地址
 //如果想完全的深度拷贝数组,目前想到的只有递归遍历,还没有想到更好的办法
 
(3).对象的深度拷贝
// 对象只有一层时
const a = {
    name:'张三',
    age:18
}
const b = Object.assign({},a)
console.log(a === b)  // 此时返回的是false

//如果对象有多层
const a = {
    name:'张三',
    age:18,
    score:{
        'php':99,
        'js':100
    }
}
// true 多层对象时用assign只能保存第一层是独立的,下面的层还是指向同一个地址
const c = Object.assign({},a)
console.log(a.score === c.score)  

// JSON.parse 和 JSON.stringify  配合使用,才可以完成对象的完全深度拷贝
const b = JSON.parse(JSON.stringify(a))
console.log(a.score === b.score)  // false