JavaScript - 淺複製



淺複製

在 JavaScript 中,淺複製是指複製陣列或物件,它複製了頂層元素,但沒有複製其巢狀結構。當建立陣列的淺複製時,常用的方法包括使用展開運算子([...])、Array.from() 或 slice() 方法。

對於物件,常用的方法是展開運算子({...}) 和 Object.assign()。需要注意的是,雖然頂層語句正在被複制,但任何在原始結構中的巢狀物件或陣列都不會被克隆,而是保留其在淺複製中的引用。

因此,對複製版本中巢狀結構的修改會影響原始版本,反之亦然。對於深度克隆,其中巢狀結構也會被複制,需要使用其他技術或庫,例如 lodash 的 _.cloneDeep。

深度複製與淺複製

複製物件或陣列有兩種方法:深度複製和淺複製。深度複製建立了一個完全獨立的副本,甚至包括巢狀結構;相反,淺複製只複製頂層元素,同時保持對巢狀元素的引用。

雖然深度複製保證了完全的獨立性,但淺複製更節省記憶體且速度更快,但代價是:巢狀結構中的修改會影響原始物件和複製物件。任務需求決定了選擇:對於完全的獨立性,首選深度複製;但是,當效率至關重要並且可以保留巢狀引用時,淺複製成為最佳選擇。

示例

示例 1:使用 Object assign() 方法進行淺複製

在下面的示例中,我們使用 Object.assign() 方法建立物件的淺複製。

<!DOCTYPE html>
<html>
<body>
   <h2>Shallow copy using Object.assign() method</h2>
   <p>Original Object:</p>
   <p id="originalObject"></p>
   <p>Copied Object:</p>
   <p id="copiedObject"></p>
   <script>
      const originalObject = { name: "Alice", age: 30 };
      const copiedObject = Object.assign({}, originalObject);
      document.getElementById("originalObject").textContent = JSON.stringify(originalObject);
      document.getElementById("copiedObject").textContent = JSON.stringify(copiedObject);
   </script>
</body>
</html>

示例 2:使用展開運算子進行淺複製

在這個示例中,我們使用展開運算子 (...) 建立陣列的淺複製。

<!DOCTYPE html>
<html>
<body>
   <h2>Shallow copy using spread operator (...)</h2>
   <p>Original Array:</p>
   <p id="originalArray"></p>
   <p>Copied Object:</p>
   <p id="copiedArray"></p>
   <script>
      const originalArray = [1, 2, 3];
      const copiedArray = [...originalArray];
      document.getElementById("originalArray").textContent = JSON.stringify(originalArray);
      document.getElementById("copiedArray").textContent = JSON.stringify(copiedArray);
   </script>
</body>
</html>

示例 3:包含陣列的物件的淺複製

在下面的示例中,結合使用 Object.assign() 和 Array.prototype.slice() 建立物件的淺複製,強調了在物件結構中正確處理陣列的方法。

<!DOCTYPE html>
<html>
<body>
   <h2>Shallow copy using array slice() method</h2>
   <p>Original Object:</p>
   <p id="originalObject"></p>
   <p>Copied Object:</p>
   <p id="copiedObject"></p>
   <script>
      const originalObject = { name: "Bob", hobbies: ["reading", "coding"] };
      const copiedObject = Object.assign({}, originalObject, { hobbies: originalObject.hobbies.slice() });
      document.getElementById("originalObject").textContent = JSON.stringify(originalObject);
      document.getElementById("copiedObject").textContent = JSON.stringify(copiedObject);
   </script>
</body>
</html>

示例 4:帶巢狀物件的淺複製

在這個示例中,我們演示了使用 JavaScript 的 JSON.stringify 和 JSON.parse 方法建立帶巢狀屬性的物件的淺複製。原始物件包含一個巢狀結構,該結構具有 name 和 address 等屬性。Address 進一步包含 street 和 city 等屬性。然後,我們使用 JSON.stringify 將原始物件轉換為 JSON 格式的字串,然後應用 JSON.parse 將字串解析回一個新物件,從而建立淺複製。

<!DOCTYPE html>
<html>
<body>
   <h2>Shallow Copy with Nested objects using JSON.stringify & JSON.parse</h2>
   <p>Original Object:</p>
   <pre id="originalObject"></pre>
   <p>Copied Object:</p>
   <pre id="copiedObject"></pre>
   <script>
      const originalObject = {
         name: "Charlie",
         address: {
            street: "123 Main St",
            city: "New York"
         }
      };

      const copiedObject = JSON.parse(JSON.stringify(originalObject));

      document.getElementById("originalObject").textContent = JSON.stringify(originalObject, null, 2);
      document.getElementById("copiedObject").textContent = JSON.stringify(copiedObject, null, 2);
   </script>
</body>
</html>

示例 5:修改對淺複製的影響

說明了使用 JavaScript 的 Object.assign() 方法建立的淺複製的修改影響,以下程式碼最初顯示了一個原始物件。原始物件具有名為“name”和“age”的屬性,以及其相應的淺複製。接下來,我們觀察這段程式碼如何更改複製物件的“age”屬性。隨後,程式碼展示了修改後原始物件和複製物件的狀態。此示例強調,儘管在複製物件內進行修改,但對淺複製的更改不會影響基礎物件;它從而確認了一種特殊行為,其中淺複製捕獲頂層屬性,同時保持主例項和輔助例項之間的獨立性。

<!DOCTYPE html>
<html>
<body>
   <h2>Shallow Copy impact of modification</h2>
   <h3>Before Modification</h3>
   <p>Original Object</p>
   <pre id="originalObjectBefore"></pre>
   <p>Copied Object</p>
   <pre id="copiedObjectBefore"></pre>
   <h3>After Modification</h3>
   <p>Original Object</p>
   <pre id="originalObjectAfter"></pre>
   <p>Copied Object</p>
   <pre id="copiedObjectAfter"></pre>
   <script>
      const originalObject = { name: "Alice", age: 30 };
      const copiedObject = Object.assign({}, originalObject);

      document.getElementById("originalObjectBefore").textContent = JSON.stringify(originalObject, null, 2);
      document.getElementById("copiedObjectBefore").textContent = JSON.stringify(copiedObject, null, 2);

      copiedObject.age = 40;

      document.getElementById("originalObjectAfter").textContent = JSON.stringify(originalObject, null, 2);
      document.getElementById("copiedObjectAfter").textContent = JSON.stringify(copiedObject, null, 2);
   </script>
</body>
</html>

淺複製的重要性

為了保留原始資料結構並有效管理記憶體,必須批判性地理解 JavaScript 中的淺複製:它複製頂層元素,這是一個取得平衡的概念。這種理解賦予了非破壞性操作任務的權力;例如,陣列排序。此外,它簡化了功能實現過程,如撤消/重做功能,同時顯著增強了整體使用者體驗——這確實是不可或缺的作用。能夠熟練處理實際應用中更改的淺複製維護資料完整性:當在某些情況下需要將修改與原始物件隔離時,這是一個至關重要的方面。

廣告