JavaScriptで最も使われる2つのデータ構造は Object と Array です。
- オブジェクトを使用すると、データ項目をキーごとに格納する単一のエンティティを作成できます。
- 配列は順序付けされたリストにデータ項目を集めることができます。
ですが、これらを関数にわたすとき、オブジェクト/配列全体は必要としない場合があります。個々の部分が必要な場合です。
分割代入(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)に対して使うことができます:
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
以前のチャプターで、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
}