深複製和淺複製只針對像 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...