浅拷贝与深拷贝的区别

51 阅读2分钟

在介绍以上两个概念之前先了解一下数据的类型

基本数据类型:是按照 存放在栈中, 占用的内存空间的大小是确定的,并由系统自动分配和自动释放。
引用数据类型: 是按照地址 存在栈中,将存放在栈内存中的地址赋值给接收的变量。当我们想要访问引用类型的值的时候,需要先从栈中获得对象的地址指针,然后,在通过地址指针找到堆中的所需要的数据。

深拷贝: 主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。
浅拷贝: 主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。

因此,如果在对对象进行赋值时,如果不希望共享对象,那么就要进行深拷贝。

第一种:使用递归的方法实现深拷贝

**

function deepClone(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==='object'){
        for(let key in obj){
            if(obj[key] && typeof obj[key]==="object"){
                objClone[key]=deepClone(obj[key])
            }else{
                objClone[key] = obj[key]
            }
        }
    }
    return objClone;
}

第二种:使用JSON.parse()和JSON.stringify()

JSON.parse(JSON.stringify(obj))

无法实现对象中方法的深拷贝

第三种:使用Object.assign()

**

Object.assign({},obj)

注意:只能深拷贝对象的一级属性,二级属性之后即为浅拷贝

数组的深拷贝

第一种:concat(arr1,arr2)

只有在数组元素是一维的时候,是深拷贝,一维以上是对值的引用

第二种:slice(idx1,idx2)

①没有参数的时候,是拷贝数组
②一个参数的时候,拷贝从起始位置到数组末尾的元素
③两个参数的时候,拷贝从起始位置到 结束位置的元素(不包含结束位置的元素,含头不含尾)
一维数组元素是深拷贝,数组元素二维以上是值的引用