JavaScriptの配列オブジェクトでmapなどの引数は分割代入を使うべし

mapなどの引数は分割代入を使うべし

JavaScriptのデータが配列オブジェクトで、例えばmapで特定のキーのみにしたいときに以下のように書いているコードを見かけます。

const items = [
  { name: 'apple', price: 100, isFruit: true },
  { name: 'banana', price: 200, isFruit: true },
  { name: 'cookie', price: 300, isFruit: false },
  { name: 'donut', price: 150, isFruit: false },
]

const nameAndPrice = items.map((item) => ({name: item.name, price: item.price}))
console.log(nameAndPrice)
// [
//   {name: 'apple', price: 100}
//   {name: 'banana', price: 200} 
//   {name: 'cookie', price: 300}
//   {name: 'donut', price: 150}
// ]

間違いではないですが、コードが冗長です。

配列オブジェクトの場合は分割代入が使用できますので、以下のように書けばもっと簡潔に書くことができます。

const items = [
  { name: 'apple', price: 100, isFruit: true },
  { name: 'banana', price: 200, isFruit: true },
  { name: 'cookie', price: 300, isFruit: false },
  { name: 'donut', price: 150, isFruit: false },
]

const nameAndPrice = items.map(({name, price}) => ({name, price}))
console.log(nameAndPrice)
// [
//   {name: 'apple', price: 100}
//   {name: 'banana', price: 200} 
//   {name: 'cookie', price: 300}
//   {name: 'donut', price: 150}
// ]

ほかにも引数に分割代入を使用したほうが良い例をfor ... of, reduce, someで説明します。

for ... ofでの分割代入の使用例

for ... of では配列オブジェクトでも for (item of items) の形式で書いてしまうケースが多いですが、例えばnameのみconsole.logで表示したい場合は for ({name} of items) { と書いたほうが簡潔に書けます。

const items = [
  { name: 'apple', price: 100, isFruit: true },
  { name: 'banana', price: 200, isFruit: true },
  { name: 'cookie', price: 300, isFruit: false },
  { name: 'donut', price: 150, isFruit: false },
]

// ❌️ Bad
for (item of items) {
  console.log(item.name)
}

// ✅️ Good
for ({name} of items) {
  console.log(name)
}

reduceでの分割代入の使用例

reduceを使用する際に配列オブジェクトでも (acc, cur) の引数を使用する人が多いですが、特定のキーのみしか使わない場合は第2引数は cur ではなく {price} のように書いたほうが簡潔に書けます。

const items = [
  { name: 'apple', price: 100, isFruit: true },
  { name: 'banana', price: 200, isFruit: true },
  { name: 'cookie', price: 300, isFruit: false },
  { name: 'donut', price: 150, isFruit: false },
]

// ❌️ Bad
const totalPrice = items.reduce((acc, cur) => acc + cur.price, 0)
console.log(totalPrice) // 750

// ✅️ Good
const totalPrice2 = items.reduce((acc, {price}) => acc + price, 0)
console.log(totalPrice2) // 750

someでの分割代入の使用例

someメソッドは配列の中の少なくとも1つの要素が合格するかどうかを判定します。

配列オブジェクトで使用する場合は特定のキーの値が少なくとも1つtrueかを判定する際に使用することが多いので、items.some({isFruit} => ... ) のように書いたほうが簡潔に書けます。

const items = [
  { name: 'apple', price: 100, isFruit: true },
  { name: 'banana', price: 200, isFruit: true },
  { name: 'cookie', price: 300, isFruit: false },
  { name: 'donut', price: 150, isFruit: false },
]

// ❌️ Bad
const hasFruit = items.some((item) => item.isFruit)
console.log(hasFruit) // true

// ✅️ Good
const hasFruit2 = items.some(({isFruit}) => isFruit)
console.log(hasFruit2) // true

これはeveryでも同様です。

const items = [
  { name: 'apple', price: 100, isFruit: true },
  { name: 'banana', price: 200, isFruit: true },
  { name: 'cookie', price: 300, isFruit: false },
  { name: 'donut', price: 150, isFruit: false },
]

// ❌️ Bad
const allAreFruit = items.every((item) => item.isFruit)
console.log(allAreFruit) // false

// ✅️ Good
const allAreFruit2 = items.every(({isFruit}) => isFruit)
console.log(allAreFruit2) // false

まとめ

reduceやsomeなどのメソッドの引数に分割代入を使用するとコードが簡潔になります。

他のメソッドでも引数に分割代入が使用可能で、使用するとコードが簡潔になりますので試してみてください。