深拷貝與淺拷貝

如何區分深拷貝與淺拷貝數組

首先咱們須要瞭解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

相關文章
相關標籤/搜索