在 JavaScript 中複製物件
各種程式語言具有各種資料結構,允許你在記憶體中組織和儲存資料。每個資料結構的工作方式都是獨一無二的。例如,在 C++ 和 Java 中,我們有 Hashmap 以鍵值形式儲存資料。同樣,在 JavaScript 中,我們有一個稱為物件的資料結構,它允許你以鍵值
格式儲存資料。
在訪問資料時,這些物件會派上用場。我們可以使用物件的鍵輕鬆訪問物件中的任何資料。在本文中,我們將看到在 JavaScript 中複製物件的各種方式。
請注意 JavaScript 物件是可變的,並且儲存為引用。如果你已經建立了一個物件並希望將其分配給其他某個物件,那麼該物件現在將儲存該物件的地址。由於我們將物件的引用儲存在另一個物件中,然後使用這個新物件,我們可以輕鬆地更改原始物件中存在的值。
var a = {'name': 'Adam', 'company': 'Google'}
var b = a;
b.name = 'Sam'
console.log(a.name, b.name);
輸出:
Sam Sam
從上面的示例中可以看出,將一個物件分配給另一個物件不會複製物件本身。它只會將舊物件的地址儲存到新物件中。
在 JavaScript 中有兩種複製物件的方法。一種方式稱為淺拷貝,另一種方式稱為深拷貝。為了實現這些方法,我們可以使用一些 JavaScript 方法,如下所示。
JavaScript 中的淺拷貝物件
在淺拷貝中,只有出現在物件第一層的鍵值
對才會被複制到新物件中。並且所有巢狀的元素或屬性,例如陣列或內部的另一個物件,都不會被複制,而是將它們的引用儲存在此物件中。
在淺拷貝中,原始物件的一些屬性也會受到影響。要理解這一點,請看下面的例子。
var obj1 = {
'firstName': 'James',
'lastName': 'Bond',
'films': ['No Time To Die', 'Spectre', 'Skyfall', 'Quantum of Solace'],
'actors':
{'characters': {'realName': 'Daniel Craig', 'fakeName': 'James Bond'}}
}
在這個例子中,我們有一個名為 obj1
的物件。要使用 JavaScript 對這個物件進行淺拷貝,我們可以使用 Object.assign()
和擴充套件運算子 ...
。讓我們使用 JavaScript 中的以下方法對 obj1
執行淺拷貝。
Object.assign()
方法
Object.assign()
方法有兩個引數。第一個引數是複製完成後將返回的 target
物件。第二個引數是我們要複製的物件:obj1
。在我們的例子中,我們將傳遞一個空物件 {}
作為目標。這是因為 obj1
中的所有元素都將被複制到這個空物件中。複製完成後,Object.assign()
將返回我們將儲存在 obj2
變數中的新物件。
var obj2 = Object.assign({}, obj1);
稍後,我們將修改此物件的屬性,我們將實際瞭解為什麼將其稱為淺拷貝。
obj2.firstName = 'Camila';
obj2.films[0] = 'abcccc';
obj2.actors.characters.realName = 'Camila';
console.log(obj1);
console.log(obj2);
輸出:
在這裡,我們使用 obj2、firstName
、films[]
陣列中的第一部電影和 actors.characters
物件中的 realName
屬性更改三個值。然後我們列印這兩個物件。
上圖顯示兩個物件中只有 firstName
屬性沒有更改。另外兩個屬性 films[]
和 realName
在這兩個物件中都發生了變化。這被稱為淺拷貝,因為 firstName
屬性是唯一的,而其他屬性對於兩個物件都是通用的,因為我們在這裡儲存地址。此處,僅複製存在於第一級的屬性。
- 展開運算子 (
...
)
rest 運算子將把 obj1
的屬性複製到 obj2
中。這類似於 Object.assign()
,我們淺拷貝物件的屬性。要使用擴充套件運算子複製物件,你必須在擴充套件符號後寫入物件名稱。
var obj2 = {...obj1};
obj2.firstName = 'Camila';
obj2.films[0] = 'abcccc';
obj2.actors.characters.realName = 'Camila';
你還將獲得我們在使用 Object.assign()
方法後獲得的相同輸出。
深度複製 JavaScript 中的物件
在深度複製中,所有鍵值
對都將被複制到新物件中。要執行深度複製,我們可以使用 JSON.parse()
和 JSON.stringify()
方法。請注意,深層複製不會複製原型物件中存在的屬性。
使用 JSON.stringify()
,我們將首先將整個物件(在本例中為 obj1
)轉換為字串,然後在 JSON.parse()
方法的幫助下,我們將解析將此字串重新轉換為 JSON 格式。
let obj2 = JSON.parse(JSON.stringify(obj1));
在這裡,你可以修改 obj2
內的任何屬性,這不會影響 obj1
內的屬性。
obj2.firstName = 'Camila';
obj2.films[0] = 'abcccc';
obj2.actors.characters.realName = 'Camila';
輸出:
我們正在修改之前修改的相同值,現在你可以注意到,當我們更改 obj2
的屬性時,它不會影響 obj1
的屬性。
Sahil is a full-stack developer who loves to build software. He likes to share his knowledge by writing technical articles and helping clients by working with them as freelance software engineer and technical writer on Upwork.
LinkedIn