JavaScript 解構賦值(destructuring syntax):讓代碼更簡潔明瞭
更新日期: 2025 年 4 月 10 日
本文為 JS 神奇 點點點 系列文:
在 ES6 之前,我們通常需要透過指定物件屬性或陣列元素的方式,來逐一獲取這些數據,這不僅繁瑣,而且讓代碼看起來不夠清晰。
但 ES6 為我們引入了解構賦值(destructuring syntax),它讓這一切變得簡單許多。
想象一下,你可以透過一行代碼,就能從一個對象或陣列中提取出你需要的多個數據,這不僅使代碼更加簡潔,而且提高了開發效率和代碼的可讀性。
物件解構賦值
基本使用
解構賦值最直接的用途,是從物件中提取多個屬性。
例如,如果我們有一個儲存個人資訊的對象,如下所示:
const person = {
name: 'Emily',
age: 28,
job: 'Designer'
};
不使用解構賦值,我們通常會這樣獲取這些資訊:
const name = person.name;
const age = person.age;
const job = person.job;
但假如「變數名稱」需要與「物件屬性名稱」相同,就可以藉由解構賦值的基本機制:根據屬性名來提取對應的值,將代碼簡化為:
const { name, age, job } = person;
這樣的語法不僅節省了多行代碼,還使得每個變量的來源——即 person 對象——變得非常明確。
自定變數名稱
不過解構賦值也提供了重新命名的功能。
這代表你可以在解構時,將屬性賦值給一個不同名稱的變數。允許你自由地選擇變數名,即使它們與對象屬性的名稱不同。
const person = {
name: 'Alice',
age: 25
};
// 重新命名解構出的變數
const { name: userName, age: userAge } = person;
console.log(userName); // Alice
console.log(userAge); // 25
這裡,name 屬性被賦值給了新的變數 userName,age 屬性被賦值給了新的變數 userAge。
這樣的語法提供了額外的靈活性,使得你不必受限於原始物件屬性的命名。
巢狀解構
解構賦值也可以應用於巢狀結構的物件。
當物件的屬性值本身也是一個物件時,我們可以使用巢狀解構來提取深層屬性:
const userProfile = {
name: 'Laura',
preferences: {
theme: 'dark',
language: 'English'
}
};
const {
name,
preferences: { theme, language }
} = userProfile;
在這個例子中,我們從 userProfile 對象中解構出 name 屬性。
同時從嵌套的 preferences 對象中解構出 theme 和 language 屬性。這種方法使得從複雜的數據結構中提取數據變得簡單明了。
默認值
解構賦值還允許指定默認值,這在處理可能不存在的屬性時特別有用。例如:
const { phone = 'No phone number' } = person;
這裡,如果 person 對象中不存在 phone 屬性,則 phone 變量將被賦予默認值 “No phone number”。
這樣可以防止代碼在訪問未定義屬性時出錯,同時提供更穩健的數據處理能力。
你這段文章寫得很清楚,語言也很平易近人!確實,為了更完整地介紹「解構賦值」,補上「函式參數中的解構賦值」這一節非常有幫助,尤其對 React 的學習者來說更是必備。
下面是我幫你撰寫的補充段落,可以自然接續你目前的文章內容,作為新增的章節:
函式參數解構
除了在宣告變數時使用解構賦值,我們也可以在函式的參數中直接使用解構,這在 React 等現代 JavaScript 開發中非常常見。
基本用法
假設我們有一個函式要處理一個使用者物件:
const user = {
name: 'Kevin',
age: 30,
job: 'Engineer'
};
function showInfo(user) {
console.log(user.name);
console.log(user.age);
}
這樣的寫法沒問題,但我們可以進一步簡化它,直接在參數中解構:
function showInfo({ name, age }) {
console.log(name);
console.log(age);
}
這樣一來就不需要在函式內部一層一層地取值,變數也更直觀。呼叫方式保持一樣:
showInfo(user); // Kevin, 30
配合預設值
你也可以在函式參數解構時設定預設值,處理沒有傳入對應資料的情況:
function greet({ name = '訪客' }) {
console.log(`Hello, ${name}!`);
}
greet({ name: 'Amy' }); // Hello, Amy!
greet({}); // Hello, 訪客!
這樣的語法讓函式更具有容錯性,對於處理 API 回傳資料或不確定結構的物件特別實用。
陣列解構賦值
基本用法
解構賦值可以用於從陣列中提取元素,並將它們賦值給變量。
例如,假設我們有一個數字陣列:
const numbers = [1, 2, 3, 4, 5];
如果我們想要提取前三個元素,不使用解構賦值,我們可能會這樣寫:
const first = numbers[0];
const second = numbers[1];
const third = numbers[2];
使用解構賦值,我們可以將上述代碼簡化為:
const [first, second, third] = numbers;
這種寫法不僅節省了多行代碼,還使得每個變量的來源——即 numbers 陣列——變得非常明確。
跳過元素
在使用解構賦值時,你可以選擇跳過陣列中的某些元素。這在你只需要部分數據時非常有用。
例如,如果我們只需要第一個和第三個數字,可以這樣寫:
const [first, , third] = numbers;
這裡,逗號用來占位,表示跳過了第二個元素,直接提取第三個元素。
使用剩餘運算符
當你想要提取陣列中的一部分元素,而將其餘的元素保留在一個新的陣列中時,可以使用剩餘運算符(…)。
這是解構賦值的一個非常有用的特性。例如:
const [first, second, ...rest] = numbers;
在這個例子中,first 和 second 分別獲得了陣列的前兩個元素,而 rest 則是一個新的陣列,包含了 numbers 中剩下的元素([3, 4, 5])。
此方法經常用在函數參數中,這可以讓函數處理陣列數據變得更加方便。
例如,一個簡單的函數,它接受一個陣列,並返回第一個和最後一個元素:
function getFirstAndLast([first, ...rest]) {
const last = rest.pop();
return { first, last };
}
const numbers = [1, 2, 3, 4, 5];
const result = getFirstAndLast(numbers);
console.log(result); // { first: 1, last: 5 }
在這個例子中,我們在函數的參數只用陣列解構賦值的語法。
當我們調用 getFirstAndLast 函數,將 numbers 數組作為參數傳入。
first 變量將被賦值為傳入數組的第一個元素(1),而 …rest(剩餘運算符)則將數組中剩下的元素收集到一個新的數組 rest 中([2, 3, 4, 5])。
函式參數中的陣列解構
和物件一樣,你也可以在函式的參數中對陣列進行解構,這讓函式處理陣列型資料更加靈活與直覺。
以下是一個簡單的範例:取得陣列的第一個和最後一個元素。
function getFirstAndLast([first, ...rest]) {
const last = rest.pop();
return { first, last };
}
使用方式如下:
const numbers = [1, 2, 3, 4, 5];
const result = getFirstAndLast(numbers);
console.log(result); // { first: 1, last: 5 }
在這個範例中:
first
直接從參數陣列中解構為第一個元素...rest
收集剩下的元素成為陣列[2, 3, 4, 5]
rest.pop()
取出最後一個元素(5)當作last
這樣一來,你就可以在函式定義中同時處理開頭與結尾的元素,不需在函式內多寫額外的索引邏輯。
結論
透過這些例子,我們可以看到解構賦值在處理陣列時的靈活性和強大功能。
這種技術不僅可以簡化代碼,還可以使代碼更易於理解和維護。