【STEP.10】
JavaScriptの分割代入をマスターしよう!

分割代入とは

分割代入(destructuring assignment)とは、配列/オブジェクトを分解し、配下の要素/プロパティ値を個々の変数に分解するための構文のことをいいます。

分割代入(配列編)

たとえば、従来であれば、配列から値を取り出すためには、以下のように個々の要素にアクセスしなければなりませんでした。

let data = [85,625,124,830,227];
let x0 = data[0];
let x1 = data[1];
let x2 = data[2];
...要素の個数だけ列挙...

しかし、分割代入を利用することで、これを一行にまとめることができます。

let data = [85,625,124,830,227];
let [x0,x1,x2,x3,x4] = data;

console.log(x0);
// 結果:85
...中略...
console.log(x4);
// 結果:227

これで配列要素が個々のx0、x1…に割り当てられます。

代入先の変数もまた、ブラケット([])でくくっている点に注目です。

配列要素と、代入先の変数は1:1でなくてもよい

配列要素と、代入先の変数は1:1でなくともかまいません。

let data = [85,625,124,830,227];
let [x0,x1,x2] = data;
let [y0,y1,y2,y3,y4,y5] = data;

console.log(x0);
// 結果:85
console.log(x1);
// 結果:625
console.log(x2);
// 結果:124
console.log(y0);
// 結果:85
...中略...
console.log(y4);
// 結果:227
console.log(y5);
// 結果:undefined

配列サイズよりも変数の個数が少ない場合(let [x0,x1,x2] = data;)は、残りの要素は無視されますし、変数の個数が多い場合(let [y0,y1,y2,y3,y4,y5] = data;)、値の割り当てられない変数はundefinedとなります。

「…」演算子で残りの要素をまとめることができる

演算子を利用することで、分割しきれなかった残りの要素をまとめて部分配列として切り出すこともできます。

let data = [85,625,124,830,227];
let [x0,x1,x2,...last] = data;

console.log(x0);
// 結果:85
console.log(x1);
// 結果:625
console.log(x2);
// 結果:124
console.log(last);
// 結果:[830,227]

分割代入,残りの要素をまとめて変数に

次のようにを除いた場合、変数lastには「830」だけがセットされ、以降の要素(227)は無視されます。

let data = [85,625,124,830,227];
let [x0,x1,x2,last] = data;

console.log(x0);
// 結果:85
console.log(x1);    
// 結果:625
console.log(x2);    
// 結果:124
console.log(last);
// 結果:830

変数の入れ替え(スワップ)

分割代入を利用すれば、2個の変数の内容を入れ替える(スワップする)ことも簡単に表現できます。

let x = 111;
let y = 999;
[x,y] = [y,x];
console.log(x,y);
// 結果:999 111

ちなみに、ES2015より前では、以下のように値を一時変数に退避させなければなりませんでした。

var x = 111;
var y = 999;
var tmp = x;
x = y;
y = tmp;
console.log(x,y);
// 結果:999 111

分割代入(オブジェクト編)

分割代入は、オブジェクトでも利用可能です。

let member = {mid: 'y001', name: '横浜流星', age: 23};
let {name, age, birthday} = member;

console.log(name);
// 結果:横浜流星
console.log(age);
// 結果:23
console.log(birthday);
// 結果:undefined

オブジェクトでは、代入先の変数も「{...}」でくくります(「[...]」(ブラケット)ではありません)。

変数の並び順は、プロパティの定義順と違っていてもかまいませんが、名前そのものは一致していなければなりません。

配列の分割代入と同様に、変数とプロパティは1:1でなくてもかまいません(変数に対応するプロパティがない場合は、undefinedになります)。

目的のプロパティが存在しなかった場合に備えて既定値を準備する

目的のプロパティが存在しなかった場合に備えて、「変数=既定値」の形式で既定値を事前に準備しておくことも可能です。

以下の例のように、nicknameプロパティが存在しないので、対応する変数nicknameには既定値「りゅうせい」がセットされます。

let member = {mid: 'y001', name: '横浜流星', age: 23};
let {name, age, nickname='りゅうせい'} = member;

console.log(nickname);
// 結果:りゅうせい

「…」演算子で残りの要素をまとめることもできる

配列と同じく、演算子を利用することで、分割しきれなかった残りの要素をまとめて部分オブジェクトとして切り出すことも可能です。

let member = {mid: 'y001', name: '横浜流星', age: 23};
let {mid, ...other} = member;
	
console.log(mid);
// 結果:y001
console.log(other);
// 結果:{name: "横浜流星", age: 23}

次のようにを省いた場合、変数otherは対応するプロパティがないのでundefinedとなります。

let member = {mid: 'y001', name: '横浜流星', age: 23};
let {mid, other} = member;

console.log(mid);
// 結果:y001
console.log(other);
// 結果:undefined

変数に別名を付ける

「変数名:別名」の形式で、元のプロパティと異なる名前の変数に値を割り当てることも可能です。

以下の例の場合、nameageプロパティは、それぞれ変数actoroldに代入されます。

let member = {mid: 'y001', name: '横浜流星', age: 23};
let {name: actor, age: old} = member;

console.log(actor);
// 結果:横浜流星
console.log(old);
// 結果:23

入れ子となったオブジェクトを分解する

入れ子のオブジェクトから値を取り出すことも可能です。

この場合は、入れ子関係が明確になるように、代入先の変数も「{...}」で入れ子を表すようにします。

let member = {
  mid: 'y001',
  name: '横浜流星',
  age: 23,
  other: {company: 'STARDUST', photo: 'y001.png'}
};
let {name, other, other: {company}} = member;

console.log(name);
// 結果:横浜流星
console.log(other);
// 結果:{company: "STARDUST", photo: "y001.png"}
console.log(company);
// 結果:STARDUST

変数の宣言と代入を分離した場合の注意点

次のように変数の宣言と分割代入の双方を切り離すことも可能です。

let member = {mid: 'y001', name: '横浜流星'};
let mid, name, age;
({mid, name, age = 22} = member);

ただし、オブジェクトの場合には、代入文全体を丸カッコでくくる必要があります。

なぜなら、そのままでは左辺の「{…}」がブロックと認識されてしまうからです。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です