2024年9月24日

分割代入

JavaScriptで最も使われる2つのデータ構造は ObjectArray です。

  • オブジェクトを使用すると、データ項目をキーごとに格納する単一のエンティティを作成できます。
  • 配列は順序付けされたリストにデータ項目を集めることができます。

ですが、これらを関数にわたすとき、オブジェクト/配列全体は必要としない場合があります。個々の部分が必要な場合です。

分割代入(Destructuring assignment) は、配列またはオブジェクトの中身を複数の変数に アンパック できるようにする特別な構文であり、非常に便利な場合があります。

分割代入(非構造化/構造の分解)は、多くのパラメータとデフォルト値を持つ複雑な関数でもうまく機能します。この後すぐにそれらを見ていきます。

Array の非構造化

配列を変数に分割する方法の例です:

// 姓名の配列があります
let arr = ["John", "Smith"]

// 分割代入
// sets firstName = arr[0]
// and surname = arr[1]
let [firstName, surname] = arr;

alert(firstName); // John
alert(surname);  // Smith

これで、配列要素の代わりに変数を扱うことができます。

split やその他配列を返すメソッドと組み合わせると便利です:

let [firstName, surname] = "John Smith".split(' ');
alert(firstName); // John
alert(surname);  // Smith

ご覧の通り、構文はシンプルです。ですがいくつかの独特な部分があります。より理解するために他の例も見ていきましょう。

“分割” は “破壊的” を意味しません

これは、項目を変数にコピーすることによって “非構造化(destructurizes)” するため、“分割代入(destructuring assignment)” と呼ばれています。 配列自体は変更されません。

これは、より短い書き方になります:

// let [firstName, surname] = arr;
let firstName = arr[0];
let surname = arr[1];
最初の要素を無視する

配列の不要な要素は、余分なカンマをつけることで捨てることができます:

// 1番目、2番目の要素が不要の場合
let [, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];

alert( title ); // Consul

上のコードでは、最初の2つの要素がスキップされ、3つ目は title に代入され、残りもスキップされています。

右辺は任意の反復可能(iterable)に対して動作します

…実際には配列だけでなく、任意の反復可能(iterable)に対して使うことができます:

let [a, b, c] = "abc"; // ["a", "b", "c"]
let [one, two, three] = new Set([1, 2, 3]);

内部的には分割代入は右辺の値に対してイテレーションすることで動作するため、これも動作します。これは = の右側の値に対して for..of を呼び出し、値を代入するためのシンタックスシュガーの一種です。

左辺では任意のものに代入することが可能です

左辺には任意の “割り当て可能なもの” を指定することができます。

例えば、オブジェクトのプロパティも指定できます:

let user = {};
[user.name, user.surname] = "John Smith".split(' ');

alert(user.name); // John
alert(user.surname); // Smith
.entries() を使ったループ

以前のチャプターで、Object.entries(obj) メソッドを見ました。

オブジェクトの key-value をループするのに、分割代入を一緒に使うこともできます:

let user = {
  name: "John",
  age: 30
};

// key-value のループ
for (let [key, value] of Object.entries(user)) {
  alert(`${key}:${value}`); // name:John, then age:30
}

Map を使用した同様のコードは、反復可能なのでよりシンプルです:

let user = new Map();
user.set("name", "John");
user.set("age", "30");

// Map は [key, value] ペアで反復します
for (let [key, value] of user) {
  alert(`${key}:${value}`); // name:John, then age:30
}