JavaScript の分割代入
ここでは JavaScript ES6 で導入された分割代入について説明します。
モダンなライブラリではバンバン使われますので、パッと見てすぐに内容を把握できるようになりましょう。
分割代入とは?
「分割代入」という名前は英語の Destructuring Assignment の翻訳です。
ストラクチャ (Structure) は名詞なら「構造」とか「構造物」という意味です。動詞もあって、動詞なら「組み立てる」などの意味になります。
デストラクチャは、ストラクチャにデをつけて打ち消していて、「『組み立て』の反対」つまり、「壊す」とか「分解する」といった意味になります。
destructuring assignment の訳語としては、既に「分割代入」という言葉が広まっているようなので、ここでも素直に「分割代入」という言葉を受けれて使いたいと思います。
それでは、何を分割したり、分解したりするのでしょうか?
分割代入というのは、「配列の要素」や「オブジェクトのプロパティ」を分解・分割して、変数(や定数)に値を代入することを指します。
JavaScript では配列は [ ] 記号で表され、オブジェクトは { } で表します。
ですから分割代入では、var、let、あるいは const に続いて [ ] や { } がきて、それらに何かを代入する形式になります。
それでは、具体的に配列の場合の分割代入、及び、オブジェクトの場合の分割代入をみていきましょう。
配列の分割代入
配列の分割代入の基本形は、次のような形になります。
const [m, n] = [1, 2];
console.log(`m=${m}, n=${n}`); // m=1, n=2
1 行目で左辺の m、n にそれぞれ、右辺の配列の要素から 1、2 が代入されます。
配列の場合、右辺と左辺の同じインデックスの要素が対応して、値が代入されます。
次の例は、上の例と同じ内容です。違う点は右辺の配列が aという文字で表されているところです。
const a = [1, 2];
const [m, n] = a;
console.log(`m=${m}, n=${n}`); // m=1, n=2
上の例では右辺も左辺も要素数が同じでしたが、必ずしも同じである必要はありません。
例えば上の配列aのひとつ目の要素だけを取り出して、代入したい場合は次のようにできます。
const [m] = a;
console.log(`m=${m}`); // m=1
二つ目の要素、4つ目の要素だけを抜き出して代入する場合は次のように書きます。
const a = [1, 2, 3, 4];
const [, m, , n] = a;
console.log(`m=${m}, n=${n}`); // m=2, n=4
次の例では、ひとつ目の要素を m に代入して、残りの要素を配列にして n に代入しています。
const a = [1, 2, 3, 4];
const [m, ...n] = a;
console.log(`m=${m}, n=${n}`); // m=1, n=2,3,4
オブジェクトの分割代入
次にオブジェクトの分割代入について説明します。
const obj = { x: 1, y: 2 };
const { x, y } = obj;
console.log(`x=${x}, y=${y}`); // x=1, y=2
この例ではプロパティ x と y をもつオブジェクトobjがあり、そこから 2 行目で x, y にプロパティの値を代入しています。
プロパティと同じ名前の変数や定数に、値を代入しています。
形式的にプロパティの部分をオブジェクトから分割して、変数を取り出していることになります。
必ずしも、プロパティと同じ名前で変数や定数を宣言する必要はありません。
次の例ではオブジェクトのプロパティ x と y をそれぞれ、P と Q という名前の定数に代入しています。
const obj = { x: 1, y: 2 };
const { x: P, y: Q } = obj;
console.log(`P=${P}, Q=${Q}`); // P=1, Q=2
孫プロパティを分割代入で取得する
プロパティにオブジェクトがセットされており、その子オブジェクトのプロパティを分割代入で取得するにはどうしたら良いでしょうか。
例えば、次のオブジェクトがあるとします。
const employee = {
firstName: 'John',
lastName: 'Doe',
address: {
street: '123 Main St.',
city: 'Honolulu',
state: 'Hawaii',
},
};
この時、cityやstate、さらに lastNameを取得するには、次のように { } を入れ子にします。
const { address: { city, state }, lastName } = employee;
console.log(city); // Honolulu
console.log(state);// Hawaii
console.log(lastName); // Doe
このような時、カンマ区切り毎に考えてコロン:の左側はプロパティを指定しているだけであり、代入は行われません。 この例では address には値が入りません。
console.log(address); // ReferenceError - address is not defined
練習にもうひとつ一段階ネストの多い、次のようなオブジェクトを考えましょう。
const obj = {
a: 'foo',
b: {
c: {
d: 'bar',
e: 100,
},
Z: 'baz',
},
};
このオブジェクトからプロパティ a と d と Zを一度に、分割代入で抜き出すにはどうしたら良いでしょうか。
このためには次のようにします。
const { a, b: { c: { d }, Z } } = obj;
console.log(`a = ${a}`); // a = foo
console.log(`d = ${d}`); // d = bar
console.log(`Z = ${Z}`); // Z = baz
この場合もやはり b や c は代入の対象ではなく、プロパティを指定しているだけです。
以上、ここでは JavaScript の分割代入について説明しました。