深拷貝與淺拷貝

深拷貝和淺拷貝的區(qū)別

當A復制B的值時,B改變了,A也跟著變,這就是淺拷貝;如果改變B的值,A不改變,那么就是深拷貝,是拷貝對象各個層級的屬性。

要想區(qū)分深拷貝和淺拷貝,需要先了解幾種數據類型:

基本數據類型:number,string,boolean,null,undefined
引用數據類型:對象,數組,函數

基本類型--名值存儲在棧內存中,例如let a=1;
a.jpg

當你b=a復制時,棧內存會新開辟一個內存,例如這樣:


b.jpg

如果此時修改a=2,并不會影響b的值,但是深拷貝一般是指復雜的object類型的數據。

引用數據類型--名存在棧內存中,值存在于堆內存中,但是棧內存會提供一個引用的地址指向堆內存中的值
c.jpg

當b=a時,復制的是a的一個引用地址,指向堆內存的值


d.jpg

當我們對a[0]=1進行修改時,堆內存里面的值也被改變了


e.jpg

堆內存中也開辟一個新的內存專門為b存放值,就像基本類型那樣,就達到深拷貝的效果了


f.jpg

實現深拷貝的方法

1.遞歸復制

function deepClone(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] = deepClone(obj[key]);
                }else{
                    //如果不是,簡單復制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}    
let a=[1,2,3,4],
    b=deepClone(a);
a[0]=2;
console.log(a,b);

2.Jq的extend方法

語法:$.extend( [deep ], target, object1 [, objectN ] ),
deep:true是深拷貝,false是淺拷貝,
target:Object類型 目標對象,其他對象的成員屬性將被附加到該對象上。,
object1:可選,可選。 Object類型 第一個被合并的對象。,
objectN:可選。 Object類型 第N個被合并的對象。

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

3.JSON對象的parse和stringify

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

注意slice方法可以拷貝一級屬性但是不能拷貝二級及以下,所以不是深拷貝

文章來源:
https://www.cnblogs.com/echolun/p/7889848.html
https://zhuanlan.zhihu.com/p/26282765,
https://www.cnblogs.com/penghuwan/p/7359026.html#_label0

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容