深拷贝与浅拷贝

如何区分深拷贝与浅拷贝数组

首先咱们须要了解js的数据类型函数

Javascript共有7种数据类型,又分为基本数据类型与复杂的数据类型(引用数据类型)
   
   基本数据类型:number,string,boolean,undefind;null,
   复杂数据类型:object 能够分红3个子类型【狭义的对象(object),数组(array),函数(function)】
   ES6新增的Symbol ,表示独一无二的值,最大的用法是用来定义对象的惟一属性名。

浅拷贝code

let a=[0,1,2,3,4]
let b=a;
console.log(a===b); //true
a[0]=1;
console.log(a,b);
//a:[1,1,2,3,4]
//b:[1,1,2,3,4]

因为引用数据类型--名存在栈内存中(存的只是个地址,该地址指向堆内存),值存在于堆内存中。b=a只是把引用地址赋值给了b,当修改数组的时候a,b依旧是指向同一个堆内存。所以修改a,b会跟着变。对象

深拷贝递归

let c=1
let d=a;
c=2
//c:2
//d:1

因为基本类型--名值存储在栈内存中,当d=c时栈内存会新开辟一个内存存放d与d的值,所以修改c=2,对d不会形成影响。但这也不算深拷贝,深拷贝自己只针对较为复杂的object类型数据,深拷贝,是拷贝对象各个层级的属性。ip

经过上面的两个例子,咱们能够得出,若是在堆内存中开辟一个新的内存专门为b存放值,像基本类型那样,就达到深拷贝的效果了。内存

使用JSON进行深拷贝string

function deep(obj){
    let obj = JSON.stringify(obj)
    let objClone = JSON.parse(obj);
    return objClone
}    
let a=[0,1,[2,3],4]
let b=deep(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);

使用递归进行深拷贝io

function deep(obj){
    let objClone = Array.isArray(obj)?[]:{};
    if(obj && typeof obj==="object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                //判断ojb子元素是否为对象,若是是,递归复制
                if(obj[key]&&typeof obj[key] ==="object"){
                    objClone[key] = deep(obj[key]);
                }else{
                    //若是不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}    
let a=[1,2,3,4]
let b=deep(a)
a[0]=2;
console.log(a,b);

总结:简单来讲深拷贝就是赋值,浅拷贝就是赋对象。console

相关文章
相关标签/搜索