プログラムはできるだけシンプルに分かりやすく記述することで、バグや認識違いを少なくすることができます。
JavaScriptの分割代入は、プログラムをシンプルに記述することができる手法の1つです。
本記事では、JavaScriptの分割代入について解説します。
記事内に記載しているプログラムは、Node.js14.14.0を使って動作確認をしています。
JavaScriptの分割代入
JavaScriptの分割代入について、以下の内容を解説します。
- JavaScriptの分割代入とは
- 配列の分割代入
- オブジェクトの分割代入
- 配列とオブジェクトの分割代入の組み合わせ
JavaScriptの分割代入とは
分割代入(Destructuring assignment)とは、配列の値やオブジェクトのプロパティを取り出して、個別の変数に代入する構文です。
ES6(ES2015)より追加された機能です。
基本的な構文は、以下の通りです。
- 配列の分割代入
- 代入先となる左辺を [] で括って、中に変数を列挙する。右辺に代入元となる配列を指定する。
- [代入先変数名1, 代入先変数名2,…] = 代入元配列
- オブジェクトの分割代入
- 代入先となる左辺を {} で括って、中に変数を列挙する。右辺に代入元となるオブジェクトを指定する。
- {代入先変数名1, 代入先変数名2,…} = 代入元オブジェクト
配列の分割代入
基本形
まずは基本形ですが、分割代入ではない、これまでのやり方で行うと以下のようになります。
arr = [1, 2, 3]; v1 = arr[0]; v2 = arr[1]; v3 = arr[2]; console.log(v1); // -> 1 console.log(v2); // -> 2 console.log(v3); // -> 3
分割代入を使うと以下のようになります。
arr = [1, 2, 3]; [d1, d2, d3] = arr; console.log(d1); // -> 1 console.log(d2); // -> 2 console.log(d3); // -> 3
それぞれの変数への代入が1行で記述できて分かりやすくなりました。
デフォルト値の利用
分割代入する変数には、配列から取り出した値がundefinedだった場合に使用されるデフォルト値を指定できます。
デフォルト値を指定するには、変数の後に = で指定します。
arr = [1, 2]; [x=97, y=98, z=99] = arr; console.log(x); // -> 1 console.log(y); // -> 2 console.log(z); // -> 99
上記のプログラムでは、代入元のarrに2つの値が入っているので、xとyには2つの値が代入されますが、3つ目のzはundefinedとなるため、デフォルト値の99が代入されます。
変数の入れ替え
分割代入の際に、変数の値を入れ替えることができます。
a = 1; b = 2; [a, b] = [b, a]; console.log(a); // -> 2 console.log(b); // -> 1
上記のプログラムでは、代入元の配列にてaとbの順番を入れ替えることで、各変数に入る値を入れ替えています。
以下のように、配列の中身を入れ替えることもできます。
arr = [1, 2, 3]; [arr[2], arr[0]] = [arr[0], arr[2]]; console.log(arr); // -> [ 3, 2, 1 ]
上記のプログラムでは、配列の参照渡しを利用して、元の配列の先頭と末尾の値を入れ替えています。
戻り値の解析
関数の戻り値に対しても、分割代入ができます。
f = () => [1, 2]; [a, b] = f(); console.log(a); // -> 1 console.log(b); // -> 2
上記のプログラムでは、関数fが戻り値として配列を返し、それを分割代入でaとbに代入しています。
不要な値の代入をしない
これまでの分割代入は、配列の先頭から順番に代入していましたが、不要な場合は代入しないこともできます。
f = () => [1, 2, 3]; [a, , b] = f(); console.log(a); // -> 1 console.log(b); // -> 3
上記のプログラムでは、関数fが3つの値を持つ配列を返しますが、戻り値の分割代入で先頭と末尾の値をaとbに代入しています。
代入が不要な場合は、カンマのみで変数を記述しないことで、必要な値のみを取得することができます。
代入をまとめる
分割代入で不要ではないが、わざわざ変数に割り当てるほどでもないという場合には、末尾の値の代入をまとめることができます。
f = () => [1, 2, 3, 4, 5]; [a, b, ...others] = f(); console.log(a); // -> 1 console.log(b); // -> 2 console.log(others); // -> [ 3, 4, 5 ]
上記のプログラムでは、配列の5つの値のうち、先頭の2つの値を変数に代入し、それ以降はまとめて1つの変数に代入しています。
まとめた部分は残りの配列となります。
正規表現の一致からの値取得
分割代入の応用編として、よく使われるのが正規表現で一致した値の取得をそれぞれの変数に代入する方法です。
url = "https://javascript-example.jp/destructuring/assignment" parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url); [, protocol, host, path] = parsedURL; console.log(protocol); // -> https console.log(host); // -> javascript-example.jp console.log(path); // -> destructuring/assignment
上記のプログラムでは、URLをプロトコル、ホスト、パスに分割して、それぞれの変数に代入しています。
正規表現についての詳しい説明は、以下の記事もご参照ください。
オブジェクトの分割代入
基本形
オブジェクトの分割代入は以下のようなプログラムになります。
o = {index: 1, name:"abc"}; const {index, name} = o; console.log(index); // -> 1 console.log(name); // -> abc
上記のプログラムでは、オブジェクトのプロパティであるindexとnameをそれぞれ分割された変数として代入しています。
プロパティ名と代入する変数名を一致させることで、分割して取り出すことができるようになっています。
変数名の変更
分割代入する変数名をオブジェクトのプロパティ名とは異なる名前にしたい場合は、変更後の変数名を一緒に指定します。
o = {index: 1, name:"abc"}; const {index: i, name: n} = o; console.log(i); // -> 1 console.log(n); // -> abc
上記のプログラムでは、プロパティ名のindexをiに変更し、nameをnに変更しています。
デフォルト値の利用
オブジェクトの分割代入でもデフォルト値を利用することができます。
var {a = 10, b = 5} = {a: 3}; console.log(a); // -> 3 console.log(b); // -> 5
上記のプログラムでは、bに対するプロパティがないため、デフォル値の5が代入されます。
分割代入の残りの取得
配列と同様に、分割代入しないプロパティを1つの変数にまとめて取得することができます。
var {a, b, ...others} = {a: 3, b: 5, c: 7, d: 9}; console.log(a); // -> 3 console.log(b); // -> 5 console.log(others); // -> { c: 7, d: 9 }
上記のプログラムでは、プロパティのcとdがまとまったオブジェクトとして代入されます。
関数の引数に対する分割代入
関数で渡される引数に対しても、分割代入をすることができます。
f = ({index, fullname: {firstname: name}}) => `${index} : ${name}`; var user = { index: 10, fullname : { firstname: "Taro", lastname: "Yamada" } }; console.log(f(user)); // -> 10 : Taro
上記のプログラムでは、関数fにて引数として渡されたオブジェクトからindexとfirstname(変数名をnameに変更)を取り出し、それらを繋げた文字列を返しています。
オブジェクトの構造を分解して、代入することで、必要な値だけを取得できます。
また、関数を呼び出す方もオブジェクトをそのまま渡すだけなので、シンプルに記述することができます。
配列とオブジェクトの分割代入の組み合わせ
配列とオブジェクトが組み合わされた複雑なものでも、構造をきちんと指定することで、分割代入することが可能です。
datalist = [ {index: 1, data: "abc"}, {index: 2, data: "opq"}, {index: 3, data: "xyz"} ]; var [, , {data}] = datalist; console.log(data); // -> xyz
上記のプログラムでは、オブジェクトが3つある配列から、3つ目の値のdataプロパティを取り出しています。
配列なのでループを使って、各値を分割代入するようなこともできます。
まとめ
JavaScriptの分割代入についてまとめると、以下になります。
- 分割代入とは、ES6で追加された機能で、配列の値やオブジェクトのプロパティを取り出して、個別の変数に代入する構文である。
- 配列やオブジェクトの構造から必要な値を取得したり、関数の戻り値や引数でも分割代入することができる。
- 正規表現の解析やJSONデータの解析に応用でき、プログラムをシンプルに記述することができる。
複雑な構造となっているデータを扱う際は、ぜひ分割代入を使ってシンプルなプログラムとなるようにしましょう。
今回はJavaScriptの分割代入について解説しました。
以上、参考になれば幸いです。
コメント