解構賦值:深拷貝還是淺拷貝

在JavaScript中,解構賦值是一項非常方便的操作。通過解構賦值,我們可以輕鬆地將數組或對象的成員值分配給變量。但是,使用解構賦值時,我們需要了解它所使用的是深拷貝還是淺拷貝的機制。在這篇文章中,我們將從多個方面詳細闡述解構賦值的深拷貝和淺拷貝機制。

一、基礎知識

  解構賦值是以「結構」為單位來進行賦值的操作。例如,我們可以使用數組或對象的鍵來將它們的值分配給變量,例如:

“`javascript
const arr = [1, 2, 3];
const [x, y, z] = arr;
console.log(x, y, z); // 1 2 3
“`
“`javascript
const obj = { foo: ‘hello’, bar: ‘world’ };
const {foo, bar} = obj;
console.log(foo, bar); // hello world
“`

  解構賦值的核心是綁定。它會把右側的值綁定到左側的變量上。

二、基本類型

  在解構賦值中,基本類型是屬於淺拷貝的範疇。具體來說,如果我們使用解構賦值將一個基本類型數據賦給另一個變量,那麼這兩個變量將指向同一個內存地址。例如:

“`javascript
let a = ‘hello’;
let b = a; // 直接複製
console.log(a, b); // hello hello
a = ‘world’;
console.log(a, b); // world hello
“`

  在這個例子中,儘管我們改變了變量a的值,但變量b的值仍然是原始的「hello」值。這是因為基本類型的賦值時採用的是值傳遞,這種特性也被延續到了解構賦值中。

  可以用下面的代碼對解構賦值的淺拷貝進行證明:

“`javascript
let a = { foo: ‘hello’ };
let b = { …a }; // 通過擴展運算符進行淺拷貝
console.log(a, b); // { foo: ‘hello’ } { foo: ‘hello’ }
a.foo = ‘world’;
console.log(a, b); // { foo: ‘world’ } { foo: ‘hello’ }
“`

  在這個例子中,我們使用了擴展運算符進行了一個表面上是完整拷貝的操作,但其實這裡只是進行了淺拷貝。當我們修改變量a的屬性foo時,變量b並沒有跟着修改,因為兩個變量只是引用了同一個對象的地址。

三、引用類型

  引用類型是指對象、數組和函數。當我們用解構賦值時,它們屬於深拷貝範疇。例如:

“`javascript
let a = { foo: { bar: ‘hello’ } };
let b = { …a }; // 通過擴展運算符進行淺拷貝
console.log(a, b); // { foo: { bar: ‘hello’ } } { foo: { bar: ‘hello’ } }
a.foo.bar = ‘world’;
console.log(a, b); // { foo: { bar: ‘world’ } } { foo: { bar: ‘hello’ } }
“`

  儘管我們使用了擴展運算符進行了淺拷貝,但當我們修改了變量a的屬性時,變量b的引用關係並沒有改變。因此,在JavaScript中,解構賦值對引用類型的賦值採用的是深拷貝。

  同時我們可以使用Object.assign()或者JSON.parse()來進行深拷貝的複製操作。例如:

“`javascript
let a = { foo: { bar: ‘hello’ } };
let b = JSON.parse(JSON.stringify(a)); // 通過JSON來進行深拷貝複製
console.log(a, b); // { foo: { bar: ‘hello’ } } { foo: { bar: ‘hello’ } }
a.foo.bar = ‘world’;
console.log(a, b); // { foo: { bar: ‘world’ } } { foo: { bar: ‘hello’ } }
“`

  這裡通過JSON來進行深拷貝複製,可以看出深度複製是完整的。修改變量a的屬性foo的子屬性bar時,變量b的值沒有跟着改動。

四、函數參數

  在JavaScript中,我們經常將對象作為函數參數進行傳遞。使用解構賦值可以讓代碼更加簡潔易讀。例如:

“`javascript
function foo({ x = 1, y = 2 } = {}) {
console.log(x, y);
}
foo({ x: 3 }); // 3 2
foo(); // 1 2
“`

  在這個例子中,我們將解構賦值作為函數的默認參數進行傳遞。通過這樣的方式,我們可以在函數中使用解構賦值,同時也可以不傳遞參數。

  需要注意的是,當我們使用默認參數時,如果沒有傳入參數,則會被默認賦值為undefined。這樣,我們可以使用解構賦值的默認值機制來為變量提供一個默認值。例如:

“`javascript
function foo({ x = 1, y = 2 } = { x: 0, y: 0 }) {
console.log(x, y);
}
foo({ x: 3 }); // 3 2
foo(); // 1 2
“`

  在這個例子中,我們使用了解構賦值的默認參數,同時為傳遞參數的情況做了處理,使得其默認參數為x: 0, y: 0。

五、數組拼接

  在解構賦值中,我們可以使用剩餘運算符來進行數組拼接。例如:

“`javascript
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr = […arr1, …arr2];
console.log(arr); // [1, 2, 3, 4, 5, 6]
“`

  當我們使用剩餘運算符時,它所代表的是數組中的其餘元素。由於解構賦值會淺拷貝數組元素,因此我們使用剩餘運算符進行數組拼接時,其實是在創建一個新的數組,而不是在原有的數組上進行操作。

六、小結

  在這篇文章中,我們從多個方面詳細闡述了解構賦值的深拷貝和淺拷貝機制。我們了解了基礎知識、基本類型、引用類型、函數參數、數組拼接等內容。通過這樣的介紹,我們可以更好地使用解構賦值,同時避免在編寫代碼的時候出現意想不到的結果。

  代碼示例:https://codepen.io/parkouroff/pen/ZELvwvK

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/181643.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-23 06:43
下一篇 2024-11-23 06:43

相關推薦

  • Python文件路徑賦值

    Python中文件操作是非常基本的操作,而文件路徑是文件操作的前提。本文將從多個方面闡述如何在Python中賦值文件路徑。 一、絕對路徑和相對路徑 在Python中,路徑可以分為絕…

    編程 2025-04-28
  • 如何使用Python將輸出值賦值給List

    對標題進行精確、簡明的解答:本文將從多個方面詳細介紹Python如何將輸出的值賦值給List。我們將分步驟進行探討,以便讀者更好地理解。 一、變量類型 在介紹如何將輸出的值賦值給L…

    編程 2025-04-28
  • Python中賦值運算符和相等運算符解析

    Python是一種高級編程語言,它通常被用於開發 Web 應用程序、人工智能、數據分析和科學計算。在Python中,賦值運算符和相等運算符是非常常見和基本的運算符,它們也是進行編程…

    編程 2025-04-28
  • Python中賦值種類

    本篇文章將從多個方面對Python中賦值種類做詳細的闡述,包括普通賦值、序列解包賦值、鏈式賦值、增量賦值和全局賦值。 一、普通賦值 普通賦值是Python中最基礎的賦值操作,通過等…

    編程 2025-04-28
  • Python同步賦值語句的使用方法和注意事項

    Python同步賦值語句是Python中用來同時為多個變量賦值的一種方法。通過這種方式,可以很方便地同時為多個變量賦值,從而提高代碼的可讀性和編寫效率。下面從多個方面詳細介紹Pyt…

    編程 2025-04-28
  • Python用input賦值用法介紹

    本文將從多個方面詳細闡述Python中如何使用input函數來賦值,以幫助讀者更好的理解和應用該函數。 一、基礎使用 1、input函數的作用是從鍵盤輸入一行文本,並返回一個字符串…

    編程 2025-04-27
  • Python二維字典賦值

    Python中的字典是一種非常有用的數據結構,它允許開發人員將鍵值對存儲在一起以便於訪問和操作。除了普通的字典,Python還允許創建二維字典,它們是由鍵值對組成的鍵值對。這些二維…

    編程 2025-04-27
  • Python元組賦值給變量

    本文將詳細闡述Python中元組賦值給變量的多個方面,包括元組的基本操作、元組賦值、交換變量、可變和不可變元組等內容。 一、元組基本操作 元組是Python中的一個重要數據類型,它…

    編程 2025-04-27
  • 解構賦值

    解構是ES6中的一個重要特性。解構賦值語法可以將一個數組或對象中的值提取到不同的變量中,使代碼更加簡潔易懂。這篇文章將從多個方面對js解構做詳細的闡述,並給出對應的代碼示例。 一、…

    編程 2025-04-23
  • vector初始化賦值詳解

    一、基礎概念 vector是一個封裝了動態大小數組的順序容器(Sequence Container)。與C-style數組不同,它能夠根據需要自動擴展,它是連續存儲的,與數組一樣高…

    編程 2025-04-22

發表回復

登錄後才能評論