1-5 解構賦值和物件屬性名稱縮寫

解構賦值(destructuring assignment)可以幫助開發者用簡短的語法,從物件或陣列中取出所需要的資料,並建立成新的變數。物件屬性名稱縮寫(shorthand property names)則可以讓開發者用更精解的方式定義物件。讓我們從下面的說明中來了解實際的使用方式。

note

💡 Tip:簡單來說,解構賦值讓開發者可以達到快速建立變數並取值的動作。

物件的解構賦值#

物件的解構賦值很常見的情境是當我們從伺服器拿到的資料是帶有一大包內容的物件,而我們只需要用到該物件裡面的其中一些屬性,這時就很適合使用解構賦值。

舉例來說,現在從伺服器拿到一大包和商品名稱有關的資料:

// 一個帶有非常多資料的物件
const product = {
name: 'iPhone',
image: 'https://i.imgur.com/b3qRKiI.jpg',
description: '全面創新的三相機系統,身懷萬千本領,卻簡練易用。',
brand: 'Apple',
offers: {
priceCurrency: 'TWD',
price: '26,900',
},
};

假設如果現在要建立新的變數,並在變數中代入該商品的名稱(name)和描述(description)時,傳統上可能會需要這樣做:

/* 一般從物件取出屬性值,並建立新變數的做法 */
const name = product.name;
const description = product.description;

但在使用物件的解構賦值之後,可以達到快速建立變數並取值的動作

// 自動產生名為 name 和 description 的變數
// 並把 product 物件內的 name 和 description 當作變數的值
const { name, description } = product;
console.log(name); // iPhone
console.log(description); // 全面創新的三相機系統,身懷萬千本領,卻簡練易用。

如下圖所示,物件的解構賦值,會根據等號左側的「變數名稱」,自動去找等號右側 product 物件中對應的「屬性名稱」,找得到的時候變為將該屬性的值做為變數值:

Imgur

若等號左側的「變數名稱」在右側的 product 物件中並沒有對應的「屬性名稱」時,該變數一樣會被宣告,但其值會是 undefined,像是這樣:

// 因為在 product 物件中並沒有屬性名稱是 battery,因此 battery 一樣會被宣告,但其值會是 undefined
const { name, description, battery } = product;
console.log(battery); // undefined

進階:透過解構賦值取出物件中的物件#

同時你可能好奇,現在 product 物件中還有 offers 這個物件,如果要取得 offers 物件裡的 price 屬性,一樣可以透過解構賦值取出嗎?

是可以的,寫法會像這樣:

// 取出物件中的物件屬性值
const {
offers: { price },
} = product;
console.log(price); // 26,900
console.log(offers); // ReferenceError: offers is not defined

這麼做的話會先定義一個名為 price 的變數,它的值會是 product.offers.price。但要注意的是,現在就沒有宣告 offers 這個變數了,因此使用 console.log(offers) 時會出現錯誤。

如果同時需要建立 offersprice 這兩個變數,有時會這樣寫。先透過解構賦值先取出 offers,接著一樣透過解構賦值再從 offers 中取出 price

const { offers } = product; // 透過解構賦值先從 product 取出 offers
const { price } = offers; // 透過解構賦值再從 offers 中取出 price
console.log(price); // 26,900
console.log(offers); // { priceCurrency: 'TWD', price: '26,900' }

如此就可以同時取用到 product 物件中的 offers 和 price 屬性。

物件屬性名稱縮寫(Shorthand property names)#

另外,在操作物件的過程中,*當物件的屬性值是一個變數,而屬性名稱又和該變數名稱相同時可以縮寫,寫出屬性名稱即可。什麼意思呢?來看下面這個例子。

首先定義了三個變數,分別是 deviceNamecurrentPricestorage,現在想要把這三個變數當成物件 galaxyNote 的屬性值,原本會這樣寫:

const deviceName = 'Galaxy Note';
const currentPrice = 30900;
const storage = '256G';
const galaxyNote = {
deviceName: deviceName,
currentPrice: currentPrice,
storage: storage,
};
console.log(galaxyNote.deviceName); // Galaxy Note

你會注意到在上面 galaxyNote 這個物件中,「屬性名稱」和「屬性值的變數名稱」完全相同,這時候可以縮寫成這樣子:

// 當物件的「屬性名稱」和當成屬性值的「變數名稱」相同時,可以縮寫成這樣
const deviceName = 'Galaxy Note';
const currentPrice = 30900;
const storage = '256G';
const galaxyNote = {
deviceName,
currentPrice,
storage,
};
console.log(galaxyNote.deviceName); // Galaxy Note

陣列的解構賦值#

陣列同樣也有解構賦值的寫法,這在 React Hooks 中經常被使用。直接看程式碼會比較清楚,假設伺服器回傳一個陣列中包含各種廠牌的智慧型手機,而且陣列中元素的順序是照當年度銷售排行:

const mobileBrands = [
'Samsung',
'Apple',
'Huawei',
'Oppo',
'Vivo',
'Xiaomi',
'LG',
'Lenovo',
'ZTE',
];

如果想要取得當年度排行前三名的手機,並建立成變數,在沒有使用解構賦值前會需要這樣寫:

// 一般從陣列取出元素值並建立新變數的做法
const best = mobileBrands[0]; // Samsung
const second = mobileBrands[1]; // Apple
const third = mobileBrands[2]; // Huawei

這時同樣可以使用解構賦值來達到快速建立變數並取值的動作,陣列的解構賦值會依據陣列內元素的順序把值取出來,像是這樣:

// 自動建立名為 best、second、third 的變數
// 並把 mobileBrands 陣列中的第一、第二和第三個元素當作變數的值帶入
const [best, second, third] = mobileBrands;
console.log(best); // Samsung
console.log(second); // Apple
console.log(third); // Huawei

因此 mobileBrands 陣列中的第一個元素會被取出,並取名為 best;第二個元素被取出,並取名為 second,以此類推:

Imgur