【JavaScript】 分割代入はどこが便利なのか
更新日:2020/08/04
JavaScriptには分割代入という機能がある。
はじめて僕がこの機能を知ったとき、何が便利なのか理解できなかった。
だがあらためて調べてみると、意外と便利な奴であることがわかった。
そこで今回は、分割代入の解説と使いどころについてお伝えしようと思う。
分割代入とは
分割代入とは配列やオブジェクトから値を取り出して、変数に代入してくれるJavaScriptの機能です。
配列から取り出す
配列を使った分割代入は、次のように記述します。
[ 変数 , 変数 , ・・・ ] = [ 値 , 値 , ・・・ ]
変数はあらかじめ宣言をしておくか、直接letやconstを指定します。
配列を代入した変数を右辺にとることもできます。
const a = [ 値 , 値 , ・・・ ];
[ 変数 , 変数 , ・・・ ] = a;
対応する位置の変数にセットされる
配列から取り出した値は、代入先で対応する位置の変数にセットされます。
分割代入例
const [ a , b ] = [ "value a" ,"value b" ]; // 分割代入
console.log( a ); // value a
console.log( b ); // value b
上の例は、[ a , b ]という配列を作成しているのではなくて、aという変数とbという変数それぞれに値を代入しています。
つまり、次のように書き換えることができます。
分割代入書き換え
const a = "value a";
const b = "value b";
わざわざ配列風にしなくても、普通に代入していけばいいいのでは?と感じます。
ですが分割代入は便利な面があります。それについてはこの記事のの分割代入配列の便利な使い方でお伝えします。
デフォルト値を指定可能
デフォルト値を指定しておくと、右辺で要素が足りないときに値を補ってくれます。
割代入のデフォルト値
const a = [ 1 ,2 ];
const [ b , c , d = 3] = a;
console.log( b , c , d); // 1 2 3
一部を配列変数に取り込む
レスト構文を使用すると、値を配列にセットすることができます。
レスト構文で配列に取り込む
const [ a , ...b ] = [ 1 , 2 , 3 , 4 ];
console.log( a ) // 1
console.log( b ) // [ 2 , 3 , 4 ]
上の例は、値1が変数aにセットされて、残りは配列bの要素としてセットされています。
これとは逆に、スプレッド構文を使用すると、配列を展開して変数にセットできます。
スプレッド構文で配列を展開
const arry = [ 2 , 3 ];
const [ a , b , c ] = [ 1 , ...arry ];
console.log( a ); // 1
console.log( b ); // 2
console.log( c ); // 3
...arryがスプレッド構文です。
[ 1 , ...arry ]は、arryが展開されて[ 1 , 2 , 3]になっています。
レスト構文とスプレッド構文を同時に使用して、配列を組み替えることもできます。
レスト構文とスプレッド構文で配列を組み替え
const array1 = [ 1 , 2 , 3];
const array2 = [ 4 , 5 , 6];
const [ a , b , ...c ] = [ ...array1 , ...array2 ];
console.log( a ); // 1
console.log( b ); // 2
console.log( c ); // [ 3 , 4 , 5 , 6 ]
レスト構文とスプレッド構文については、次の記事で詳しく紹介しているので参考にしてください。
参考:【JavaScript】 コード中の「...」は意味があった
オブジェクトの分割代入
分割代入を使用すると、オブジェクトから指定したプロパティの値を変数に取り出すことができます。
オブジェクトの分割代入
const a = { x: 1 , y:2 , z:3 };
const { y , x } = a;
console.log( y , x ); // 2 1
a.xが変数xに、a.yが変数yに代入されます。
取り出す順番は関係ありません。
また、必要なものだけ取り出すことができます。
取り出し時に、変数名を変更することもできます。
オブジェクトの分割代入:変数名変更
const a = { x: 1 , y:2 , z:3 };
const { x:b , d:c = 3} = a;
console.log( b , c ); // 1 3
上の例はオブジェクトaからxプロパティが取り出されて、変数bに代入されています。
次にdプロパティを取り出そうとしたところ、aオブジェクトには存在していないので、変数cにデフォルト値の3を代入しています。
ちなみに宣言済みの変数を使用する場合、注意が必要です。
次のコードはエラーになります。
エラーになるパターン
let b = 1;
let c = 1;
const a = { x: 1 , y:2 };
{ x:b , d:c = 3 } = a; // エラー
行の最初の文字が { のとき、スコープをあらわすカッコとして扱われるからです。
( )で囲むと式とみなされるので、エラーが出なくなります。
エラーがでないパターン
( { x:b , z:c = 3 } = a );
関数の引数も分割代入できる
次のコードのように、関数の引数も分割代入できます。
関数の引数で分割代入
function a( [ b , c ] ,d){
console.log( b , c , d);
}
a( [ 1 , 2 ] , 3 );
通常の分割代入もそうですが、この関数の形式を始めて見たときは、非常に奇妙だと感じました。
それ以前に、意味が分かりませんでしたが…
ようするに、下のように配列を受け取る関数内で、受け取った配列を変数に代入する手間を省いているのです。
分割代入を使用しない書き方
function a( arry ,d){
const b = arry[0];
const b = arry[1];
console.log( b , c , d);
}
const arry = [ 1 , 2 ];
a( arry , 3 );
分割代入配列の便利な使い方
どんな時に分割代入を使うと便利なのかを考えてみました。
引数に名前をつける
オブジェクトの分割代入を使用すると、関数呼び出し時の引数を名前で指定できるようになります。
関数に引数を名前で指定
function a( { param1:b =1 , param2:c = 2 }){
console.log( b , c ); // 1 20
}
a( { param2:20 } );
デフォルト値を指定しているので、必要なものだけ渡すことができますね。
二つ値を入れ替える
分割代入を使用すると、一つのコードで二つ値を入れ替えることができます。
分割代入で値入れ替え
let x = 10;
let y = 20;
[ x , y ] = [ y , x ];
console.log( x , y ) // 20 10
一時的な変数を使用しなくてもいいので、コードがスッキリとしますね。
配列の戻り値を直接変数に代入
関数から複数の値を返したいとき、配列を利用することがあります。
分割代入を使用すると、直接変数に代入することができます。
配列の戻り値を分割代入で変数にセット
function a(){
return [ 1 , 2 ];
}
let [ x , y ] = a();
console.log( x , y ) // 20 10
これもコードがスッキリとしますね。
オブジェクトから必要な値のみを変数に代入
オブジェクトを返すメソッドの結果などから、必要なプロパティのみを取得できます。
オブジェクトから必要な値のみ分割代入でセット
window.addEventListener( "DOMContentLoaded" , ()=> {
const {innerText: x } = document.getElementById( "a1" );
console.log( x ) // Hello!
});
HTML
<p id="a1">Hello!</p>
最初に必要なものを抜き出しておくと、コードが見やすくなりますね。
まとめ
分割代入を使わなくても、使い方を知っておいた方がいいです。
他の人のコードを見たとき、全く意味がつかめなくなりますからね。
更新日:2020/08/04
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。