深拷貝和淺拷貝 具體實現

2021-09-27 10:01:45 字數 1733 閱讀 8510

我們先來說一下淺拷貝:

var obj = ;

var b = obj;

console.log(b)

// 輸出結果為1

這就是淺拷貝

但是淺拷貝會存在乙個問題,我們可以通過**來看一下

var obj = ;

var b = obj;

console.log(b)

我們上面通過淺拷貝拷貝了乙個引用型別,如果我們去修改obj會怎麼樣?

var obj = ;

var b = obj;

// 修改obj裡面的a屬性

obj.a = 2

console.log(b)

// 輸出結果

我們會發現通過淺拷貝乙個引用型別,如果修改obj,最終b也會跟著修改,是因為在拷貝的時候,我們只是將引用位址拷貝給了b,也就是說b和obj引用的是同乙個物件

所以我們**就要改良一下,需要將obj裡面的元素取出來然後交給b

var obj = ;

var b = {}

for(key in obj)

// 修改 obj的屬性

obj.a = 2

console.log(b)

// 輸出結果

這樣就完美的解決了問題哈哈哈

但是我們作為乙個好的程式設計師,要去發現問題,再來看下乙個問題,如果obj裡面又包含了乙個c物件,然後修改c會怎麼樣

var obj =

};var b = {}

for(key in obj)

// 修改 obj的屬性

obj.c.c1 = 2

console.log(b)

// 輸出結果為 }

當我們修改了obj裡面的c物件的時候,b裡面的c也跟著變化了,原因就是,b裡面拷貝的c也是乙個引用型別,從而拷貝的只是乙個位址,並且還有乙個問題,就是我們不知道obj裡面有多少層,可能c1裡面又包含乙個引用型別,並且我們不知道引用型別是物件還是陣列,那麼我們就要解決這個問題,這樣的問題就是深拷貝。

我們可以先利用乙個簡單方式來實現深拷貝

var obj =

};var str = json.stringify(obj)

var b = json.parse(str)

// 修改 obj的屬性

obj.c.c1 = 2

console.log(b)

我們先將需要拷貝的**利用json.stringify轉成字元轉,然後再利用

json.parse將字元轉轉回物件,即完成拷貝

但是有的面試官會問你,能夠利用遞迴實現嗎?回答當然可以

我們就再利用遞迴來實現深拷貝

遞迴實現的思路是什麼樣的?我們來分析一下

我們肯定要定義乙個方法,那麼這個方法最終應該返回乙個深拷貝的資料

既然要返回乙個資料,我們首先就要定義乙個資料,但是資料是物件還是陣列?所以需要判斷,如果要拷貝的資料是陣列,即定義乙個陣列,如果是乙個物件,即定義乙個物件

方法裡面怎麼拷貝啊?還是一樣的利用for in 迴圈,在迴圈內部,需要判斷,如果是型別是簡單型別,直接拷貝,如果是引用型別,就需要在一次的將引用型別裡面的值取出來

根據上面的邏輯我們處理一下**

var obj =

};function deepcopy(obj)

for(key in obj)else

}return copy

}var b = deepcopy(obj)

console.log(b)

淺拷貝和深拷貝具體詳解

當用乙個已經初始化了的自定義類型別物件去初始化另乙個新構造的物件的時候,拷貝建構函式就會被自動呼叫,也就是說,當類的物件需要拷貝時,拷貝建構函式將會被呼叫。以下情況都會呼叫拷貝建構函式 1 乙個物件以值傳遞的方式傳入函式體 2 乙個物件以值傳遞的方式從函式返回 3 乙個物件需要通過另乙個物件進行初始...

深拷貝和淺拷貝具體分析以及實現

如何區分深拷貝和淺拷貝呢?簡單來說 如果b複製了a,a改變了,b也跟著一起改變了,那麼就是淺拷貝,如果a改變,b沒有跟著一起改變,那麼就是淺拷貝 那麼在實際開發中我們如何進行深拷貝呢?分兩種情況 1 對基本資料型別進行深拷貝 基本資料型別 string number boolean null und...

深拷貝和淺拷貝

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