返回

揭開 JavaScript 淺拷貝與深拷貝的神秘面紗

前端

浅尝輒止,深藏不露:JavaScript 淺拷貝與深拷貝之秘

引言

在 JavaScript 的浩瀚世界裡,淺拷貝與深拷貝如同兩位隱形刺客,悄無聲息地穿梭於物件與陣列之間。它們看似相近,卻有著天壤之別,影響著程式碼的執行結果。本文將深入淺出地揭開它們的神秘面紗,帶領讀者領略這兩種拷貝技術的精妙之處。

淺拷貝:似是而非的雙生

淺拷貝,顧名思義,只拷貝物件或陣列的頂層結構。它並不會深入拷貝物件的內部屬性或陣列的元素。這就如同製作一張紙的影印本,影印本上只會顯示紙張的表面文字,而不會拷貝紙張的內容。

const obj1 = { name: 'John Doe' };
const obj2 = obj1; // 淺拷貝

obj2.name = 'Jane Doe';

console.log(obj1.name); // Jane Doe

在上述程式碼中,obj2 僅僅指向了與 obj1 相同的記憶體位置。因此,當我們修改 obj2 的屬性時,obj1 的值也會發生改變。

深拷貝:徹底複製的化身

與淺拷貝不同,深拷貝會將物件或陣列的每個屬性或元素都逐一拷貝到新的記憶體位置。這就像製作一本書的影印本,影印本上的文字和插圖都與原書一模一樣。

const obj1 = { name: 'John Doe' };
const obj2 = JSON.parse(JSON.stringify(obj1)); // 深拷貝

obj2.name = 'Jane Doe';

console.log(obj1.name); // John Doe

在這個程式碼中,我們使用 JSON.stringify() 和 JSON.parse() 來進行深拷貝。這樣一來,obj2 就會獲得一份與 obj1 完全獨立的拷貝。

記憶體管理:淺與深的博弈

淺拷貝與深拷貝對記憶體管理有著不同的影響。淺拷貝由於只拷貝頂層結構,因此耗費的記憶體較少。但是,由於它們指向同一個記憶體位置,任何對拷貝的修改都將反映在原始物件上。

深拷貝則會拷貝所有的屬性或元素,因此耗費的記憶體較多。但它的好處是,拷貝與原始物件完全獨立,不會影響彼此的狀態。

使用時機:深思熟慮的選擇

淺拷貝和深拷貝各有利弊,因此在使用時需要根據具體場景進行選擇。

  • 淺拷貝適合 :當需要一份指向相同記憶體位置的拷貝時,例如傳遞參數給函數或在物件陣列中使用拷貝。
  • 深拷貝適合 :當需要一份與原始物件完全獨立的拷貝時,例如避免物件修改的連鎖反應或儲存資料到資料庫。

深入實戰:剖析範例程式碼

在實務應用中,淺拷貝與深拷貝扮演著重要的角色。下面是一個剖析範例程式碼的實例:

const person = {
  name: 'John Doe',
  address: {
    street: 'Main Street',
    number: 123
  }
};

const shallowCopy = person;
const deepCopy = JSON.parse(JSON.stringify(person));

shallowCopy.name = 'Jane Doe';
shallowCopy.address.number = 456;

console.log(person.name); // Jane Doe
console.log(person.address.number); // 456
console.log(deepCopy.name); // John Doe
console.log(deepCopy.address.number); // 123

在這段程式碼中,我們定義了一個包含物件和巢狀物件的 person 物件。我們使用淺拷貝和深拷貝建立了 person 的拷貝。修改淺拷貝 shallowCopy 後,我們可以看到 person 物件的屬性也跟著改變了。而深拷貝 deepCopy 則不受影響,保持了與 person 物件相同的初始狀態。

結論:掌握拷貝之道,遊刃有餘

淺拷貝與深拷貝是 JavaScript 中不可或缺的拷貝技術。瞭解它們的區別和使用時機至關重要。透過善用這兩種技術,我們可以靈活地處理物件與陣列,有效地管理記憶體,並確保程式碼的正確執行。願這篇文章能為讀者們帶來更多啟發,在 JavaScript 的世界裡揮灑自如。