談談深拷貝和淺拷貝

2021-09-29 18:49:04 字數 1824 閱讀 9880

今天在做專案購物車需求的時候,遇到乙個同深拷貝、淺拷貝相關的問題,所以來談談深拷貝和淺拷貝。

什麼是深拷貝?複製基本型別的屬性;引用型別的屬性複製,複製棧中的變數 和 變數指向堆記憶體中的物件的指標和堆記憶體中的物件。

什麼是淺拷貝?複製基本型別的屬性;引用型別的屬性複製,複製棧中的變數 和 變數指向堆記憶體中的物件的指標,不複製堆記憶體中的物件。

說的通俗易懂些,就是假設b賦值給a,當修改a時,看b是否會發生變化,如果b也跟著變了,說明這是淺拷貝,如果b沒變,那就是深拷貝。在專案的過程中,要關注js**裡物件、陣列的賦值是否對頁面的顯示有影響?是否因為改變了某個值,導致其他相同級別的也隨之變化?

1、如果我們不想因為改變引用型別裡某個值,導致其他相同級別的也隨之變化,那麼對引用型別的拷貝要採用深拷貝。

網上的方法也有很多種:

(1)採用遞迴去拷貝所有層級屬性

function deepclone(obj);

if(obj && typeof obj=== 「object」 )}}

return obj2 ;

}let a=[1,2,3,4],

b=deepclone(a); // 深拷貝

a[0]=2;

(2)通過json物件來實現深拷貝

let a=[1,2,3,4],

b=json.parse(json.stringify(a)); // 深拷貝

b[0]=2

缺點: 無法實現對物件中方法的深拷貝,會顯示為undefined

(3)如果物件的value是基本型別的話,也可以用object.assign來實現深拷貝,但是要把它賦值給乙個空物件

var obj =

*var obj1 = object.assign({}, obj); // obj賦值給乙個空{}

obj1.a = 3;

console.log(obj.a);// 3

(4)像slice、concat這些陣列的操作方法都是陣列的深拷貝。

(5)使用擴充套件運算子實現深拷貝

1、當value是基本資料型別,是可以使用拓展運算子進行深拷貝的

2、當value是引用型別的值,引用型別進行深拷貝也只是拷貝了引用位址,所以屬於淺拷貝

var people=

var people1 =

console.log(people1); //

console.log(people); //

2、淺拷貝

(1)object.assign方法

var obj =

var obj1 = object.assign(obj);

obj1.a = 3;

console.log(obj.a) // 3

(2)直接用=賦值

let a=[0,1,2,3,4],

b=a;

a[0]=1;

console.log(b); // [1,1,2,3,4],

(3)遍歷物件,然後把屬性和屬性值都放在乙個新的物件

function ******copy(obj1) ;

for (let i in obj1)

}return obj2;

}var obj1 =

}var obj2 = ******copy(obj1);

obj2.a = 3;

obj2.c.d = 4;

console.log(obj1.a); // 1

console.log(obj2.a); // 3

console.log(obj1.c.d); // 4

console.log(obj2.c.d); // 4

談談拷貝中坑 深拷貝與淺拷貝

1.堆 stack 和棧 heap stack為自動分配的記憶體空間,它由系統自動釋放 而heap則是動態分配的記憶體,大小不定也不會自動釋放。2.值與引用 js中有基本資料型別和引用型別 基本資料型別的變數和值都是存放在棧中,宣告之後會分配一塊記憶體區域,基本資料型別之間的賦值是直接把棧記憶體中存...

深拷貝和淺拷貝

淺拷貝就是物件的資料成員之間的簡單賦值,如你設計了乙個沒有類而沒有提供它的複製建構函式,當用該類的乙個物件去給令乙個物件賦值時所執行的過程就是淺拷貝,如 class a a private int data int main 這一句b a 就是淺拷貝,執行完這句後b.data 5 如果物件中沒有其他...

淺拷貝和深拷貝

以下情況都會呼叫拷貝建構函式 乙個物件以值傳遞的方式傳入函式體 例如 已知class a,class b void func a a void func a a func b b 此時函式對b的操作是呼叫拷貝建構函式後的臨時拷貝物件。多數傳指標 乙個物件以值傳遞的方式從函式返回 如 return b...