今回はJavaScriptのES2015から追加された機能である分割代入について色々とまとめてみました。
最初は少し分かりにくい機能だと感じたので、実例を交えながら解説しています。
しっかり理解すれば、今までよりもかなりコードがスッキリ書けるようになるはずです。
それではやっていきましょう。
JavaScriptの分割代入って何?
まずは分割代入の機能をざっくりと確認します。
分割代入 (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。
MDN web docsより引用
少しわかりにくいので英語の意味からイメージしましょう。
以下の訳を見ると "Destructuring = 非構造化" らしいです。

その名前の通り、一旦配列やオブジェクトの構造をばらして、別の変数に順番に代入していると考えると理解しやすい気がします。
このイメージを頭に入れつつ、実例を見ていきましょう。
配列と分割代入
まずは、配列において分割代入を使った場合を見ていきます。
一番簡単な例
前から順番に、名前、年齢、趣味を表す以下のような配列があったとします。
const array = ["太郎", "20", "サッカー"];
ここで「それぞれの配列の要素を分かりやすい変数に代入したい」ということを考えます。
普通に何も考えずに書くと、以下のようにコードを書けますね。
const array = ["太郎", "20", "サッカー"];
const name = array[0];
const age = array[1];
const hobby = array[2];
配列から各要素を取り出して、変数定義を3回行っています。
このコードは分割代入を使って以下のように書き換えられます。
const array = ["太郎", "20", "サッカー"];
const [name, age, hobby] = array;
左側にいきなり配列のような記法が出てくるので、混乱するかも知れませんが、やっていることは案外単純です。
代入する配列を一度ばらして(非構造化して)それぞれの変数に代入する、ということを行っています。
複数の変数の宣言を1行で書けるのでかなりスッキリしましたね。
使いたい部分だけを使う
分割代入では自分が使いたい(変数に代入したい)部分だけを使うこともできます。
例えば、さっきと同じ配列から"前の2つだけ"を取り出したい場合は以下のようになります。
const array = ["太郎", "20", "サッカー"];
const [name, age] = array;
console.log(name); // 太郎
console.log(age); // 20
注意点として、分割代入はあくまで元の配列の順番通りに代入を行います。
そのため、今までの例で"1つ目と3つ目の要素だけ"のように、ある要素を飛ばして代入する場合は以下のように書きます。
const array = ["太郎", "20", "サッカー"];
const [name, , hobby] = array; //コンマが2つ連続してることに注意
console.log(name); // 太郎
console.log(hobby); // サッカー
配列のあまりを全部代入する
配列のあまりを新しい配列として代入することも可能です。
下の例では、最初の一つだけが変数aに代入され、それ以外は新しい配列として変数bに代入されているのが分かります。
const [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
要素の数や変数の数がいくら増えても、同じような結果になります。
const [a, b, ...c] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(b); // 2
console.log(c); // [3, 4, 5]
注意点として配列の余りを表す記法である...xは一番最後に来る必要があります。
あくまで余りですからね。以下のように...xの後に続けようとすると文法エラーになります。
const [a, ...b, c] = [1, 2, 3, 4];
// SyntaxError: rest element may not have a trailing comma
// Always consider using rest operator as the last element
変数を宣言した後に代入する
今までの例では変数の宣言と代入を同時に行っていましたが、以下のように宣言した後に代入することも可能です。
変数を宣言する部分と、代入する部分が別々なのが分かります。
個人的に、あまり使う場面は無いような気もしますね。
let a, b;
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
デフォルト値も設定できる
宣言する変数に、デフォルトの値をもたせておくこともできます。
[a=10, b=20]のような形式で書くことでデフォルト値を持ち、値が代入された部分だけが上書きされます。
let [a=10, b=20] = [5];
console.log(a); // 5
console.log(b); // 20
オブジェクトと分割代入
次に、配列において分割代入を使った場合を見ていきます。
一番簡単な例
idプロパティとemailプロパティを持つ、以下のようなuserオブジェクトを考えます。
const user = {
id: 1,
email: test@example.com
};
このidプロパティとemailプロパティを取り出して、それぞれ変数に代入したい場合を考えます。
この場合は配列と同じように以下のような記法で分割代入することが可能です。
const user = {
id: 1,
email: test@example.com
};
const { id, email } = user;
console.log(id); // 1
console.log(email); // test@example.com
上記のように書く場合は元のオブジェクトのプロパティ名と同じ名前で定義できます。
もとのオブジェクトのプロパティと違う名前を変数として定義したい場合の書き方は、次で見ていきます。
プロパティとは違う名前をつける場合
先程の例では、オブジェクトのプロパティと同じ名前の変数を定義していました。
プロパティとは違う名前をつける場合は以下のように記述します。
const user = {
id: 1,
email: test@example.com
};
const { id: userId, email: userEmail } = user;
console.log(userId); // 1
console.log(userEmail); // test@example.com
この場合はuserオブジェクトのidプロパティをuserIdという変数に、emailプロパティをuserEmailという変数にそれぞれ代入できていますね。
デフォルト値も設定できる
配列のときと同じようにデフォルトの値をもたせておくこともできます。
let {a = 10, b = 5} = {a: 3};
console.log(a); // 3
console.log(b); // 5
値が代入された変数aだけが上書きされていることが分かります。
関数の引数と分割代入
最後に関数の引数に分割代入を利用する場合を見ていきましょう。
初めて見た時に、「関数の引数に{ }がある...」と混乱した覚えがあるので解説していきます。
ただ、基本的な動きはオブジェクトの場合と同じなので慎重に見ていけば大丈夫です。
引数に渡されたオブジェクトのプロパティを参照
まずは以下のようなuserオブジェクトを例にします。
const user = {
id: 42,
name: '太郎',
};
このuserオブジェクトを引数に受け取って、そのidとnameを返すというシンプルな関数を作ることを考えてみましょう。
普通の書き方で考えれば以下のように書くことで実装できますね。
const user = {
id: 42,
name: '太郎',
};
function userId(user) {
const id = user.id;
const name = user.name;
return `IDは${id}で、名前は${name}です。`;
}
引数で受け取ったuserオブジェクトのプロパティをそれぞれidとnameという変数に詰め替えていますね。
これを今まで見てきたオブジェクトの分割代入で改善すると、以下のようになります。
const user = {
id: 42,
name: '太郎',
};
function userId(user) {
const { id, name } = user;
return `IDは${id}で、名前は${name}です。`;
}
今まで学習してきたオブジェクトの分割代入を利用して、変数を定義しています。
実はさらに改善することが可能で、以下のように引数で直接オブジェクトのような形で変数を定義できます。
const user = {
id: 42,
name: '太郎',
};
function userId({ id, name }) {
return `IDは${id}で、名前は${name}です。`;
}
書き方がかなり特殊になるので、初めは混乱するかも知れませんが、やっていることはオブジェクトの分割代入と同じです。
引数にオブジェクトが入ってきて、そのプロパティを変数として定義しているという流れを抑えておきましょう。
引数に入ってくるオブジェクトのプロパティを分割代入で変数に代入できるので、かなりスッキリ書けましたね。
最後に
今回はJavaScriptの分割代入について紹介しました。
他にもバニラJavaScriptには様々な仕様があり、昨今のフロントエンド開発においてバニラJavaScriptの基礎は超重要です。
各種フレームワークやライブラリなどを学習していると「JavaScriptの基礎をしっかりやっておいてよかった...」と感じることが多々あります。
JavaScriptの基礎知識が曖昧だと感じた人は、是非一度バニラJSをしっかり学習してみましょう。
学習ステップに関しては以下の記事でまとめています。それでは、今回は以上です。