深拷貝與淺拷貝

2022-06-17 06:24:12 字數 2369 閱讀 3761

深複製和淺複製只針對像 object, array 這樣的複雜物件的。

簡單來說,淺複製只複製一層物件的屬性,而深複製則遞迴複製了所有層級。

比如淺拷貝:

當b拷貝了a的資料,且當b的改變會導致a的改變時,此時叫b淺拷貝了a,例如:

//淺拷貝

var a=

}var b={}

var b=a;

b.name="lucy";

console.log(a.name); //lucy

a直接賦值給b後,b中name屬性的改變導致了a中name屬性也發生了變化。

第一層「深拷貝」:就是對於a物件下所有的屬性和方法都進行了深拷貝,

但是當a物件下的屬性如data是物件時,它拷貝的是位址,也就是淺拷貝,這種拷貝方式還是屬於淺拷貝。

多層深拷貝:能將a物件下所有的屬性,及時屬性是物件,也能夠深拷貝出來,讓a和b相互獨立,這種叫才叫深拷貝。

var a=,

say:function()

}var b={}

object.assign(b,a); //將a拷貝到b

b.name="lucy";

console.log(a.name); //martin,發現a中name並沒有改變

b.data.num=5;

console.log(a.data.num); //5,發現a中data的num屬性改變了,說明data物件沒有被深拷貝

直接賦值:這種方式實現的就是純粹的淺拷貝,b的任何變化都會反映在a上。

object.assign():這種方式實現的實現的是單層「深拷貝」,但不是意義上的深拷貝,對深層還是實行的淺拷貝。

當b拷貝了a的資料,且當b的改變不會導致a的改變時,此時叫b深拷貝了a,例如:

//深拷貝

var a=,

say:function()

} //開闢了乙個新的堆記憶體位址,假設為placaa

var b={}; //又開闢了乙個新的堆記憶體位址,假設為placeb

b=json.parse(json.stringfy(a));

b.name="lucy";

console.log(a.name); //martin

通過json物件方法實現物件的深拷貝,我們可以看到其中b.name值的改變並沒有影響a.name的值,因為a和b分別指向不同的堆記憶體位址,因此兩者互不影響。

理解了深淺拷貝,接下來說一下深拷貝的幾種方式。

首先假設乙個已知的物件a,然後需要把a深拷貝到b。

var a=,

say:function ()

};var b={};

function deepcopy(a,b) else

}}deepcopy(a,b);

b.data.num=5;

console.log(a.data.num); //10,a中屬性值並沒有改變,說明是深拷貝

通過這種方式能實現深層拷貝,而且能自由控制拷貝是如何進行的,如:當b中有和a同名的屬性,要不要重新賦值?這些都可以進行控制,但是**相對複雜一些。

var b=json.parse(json.stringify(a));

b.data.num=5;

console.log(a.data.num); //10,a中屬性值並沒有改變,說明是深拷貝

用這種方式實現深拷貝的時候要 , ,上述**中b也並沒有拷貝出a中的say函式,這和json.stringify方法的規則有關係,它在序列化的時候會直接忽略函式,因此最後a中的say函式沒有被拷貝到b,關於json.stringify序列化的具體規則見json.stringify指南。

遞迴:使用遞迴進行深拷貝時比較靈活,但是**較為複雜;

json物件:json物件方法實現深拷貝時比較簡單,但是當拷貝物件包含方法時,方法會被丟失;

「淺拷貝」與「深拷貝」

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...

淺拷貝與深拷貝

淺拷貝 1 2 myclass a,b a b 為了封裝性和解耦,同型別的兩個物件之間進行賦值操作時,所有成員變數被複製,包括私有成員 指標變數。類的成員函式在傳遞或返回物件時都會進行物件複製產生臨時物件,比如函式呼叫時實參變為形參,以及函式返回物件。考慮到效能和使用者要求不同,編譯器不複製物件內部...

「淺拷貝」與「深拷貝」

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...