30歳からのプログラミング

30歳無職から独学でプログラミングを開始した人間の記録。

分割代入とスプレッド演算子

分割代入

分割代入とは、配列やオブジェクトから値を取り出し、それを個別の変数に代入すること。
デストラクチャリング、Destructuring assignmentとも呼ばれる。

まずは配列を分割代入する方法から見ていく。

let [a,b] = [1,9];
console.log(a,b);   // 1 9

let x, y;
let array = ['hoge', 'fuga'];
[x, y] = array;
console.log(x); // hoge
console.log(y); // fuga

オペランドに変数を配列形式で記述し、右オペランドに配列を記述する。
そうすると右オペランドの配列から1つずつ要素を取り出し、左オペランドの変数に代入していく。
なお、特定の要素をスキップすることも出来る。

let array = [1,2,3,4];
let [a, , ,b] = array;
console.log(a,b);   // 1 4

オブジェクトの分割代入も、配列とほぼ同じ。

let obj = {
    a: 'foo',
    b: 'boo',
    c: 'hoge',
    d: 'fuga'
};

let {a,b} = obj;
console.log(a); // foo
console.log(b); // boo

let c,d;
({c,d} = obj);
console.log(c); // hoge
console.log(d); // fuga

上記の方法ではオブジェクトのキーと同名の変数に代入しているが、任意の名称の変数に代入することも可能。

let obj = {
    a: 'foo',
    b: 'boo',
    c: 'hoge',
    d: 'fuga'
};

let {a:x,b:y} = obj;

console.log(x); // foo
console.log(y); // boo

変数の入れ替え

分割代入を使えば、変数を入れ替える処理も簡単に行える。

let [a,b] = [1,9];
console.log(a,b);   // 1 9

[a,b] = [b,a];
console.log(a,b);   // 9 1

デフォルト値

分割代入ではデフォルト値を設定することも出来る。
対応する要素が存在しない(undefinedである)場合、そのデフォルト値が変数に代入される。

let a, b, c, d;

[a=5, b=6, c=7, d=8] = [1, undefined, 2];
console.log(a); // 1
console.log(b); // 6
console.log(c); // 2
console.log(d); // 8
let obj = {
    a: 'foo',
    b: 'boo'
};

let {a=1,c=2} = obj;
console.log(a); // foo
console.log(c); // 2

関数の戻り値の代入

従来は、戻り値として配列やオブジェクトを返す関数に対しては、そのまま配列やオブジェクトとして受け取るしかなく、その後で個別の要素を取り出していく必要があった。
だが分割代入を使えば、個別の要素をそのまま受け取ることが出来る。

function myFunc(x,y){
    const sum = x+y;
    const product = x*y;
    return [sum, product];
};

// 従来の方法
const answer = myFunc(4,5);
console.log('和は' + answer[0] + ', 積は' + answer[1]);
// 和は9, 積は20

// 分割代入
const [sum, product] = myFunc(4,5);
console.log('和は' + sum + ', 積は' + product);
// 和は9, 積は20

スプレッド演算子

スプレッド演算子は、...で表現される。

値を渡す際、スプレッド演算子を使って配列を渡すと、受け取った先で自動的にその配列が展開される。
具体的なケースとしては、関数の引数や、配列リテラルが考えられる。
スプレッド演算子を使わないケースと比較すると、理解しやすい。

function myFunc(a,b){
    console.log(a);
    console.log(b);
    console.log(arguments[2]);
    console.log(arguments.length);
};

let array = [1,2,3,4,5];

myFunc(array);
// [ 1, 2, 3, 4, 5 ]
// undefined
// undefined
// 1

myFunc(...array);
// 1
// 2
// 3
// 5
let array = [1,2,3];
let array2 = [4,5,6];
let array3 = [7,8,9];

console.log( [55,56,57,array] );
// [ 55, 56, 57, [ 1, 2, 3 ] ]

console.log( [55,56,57,...array] );
// [ 55, 56, 57, 1, 2, 3 ]

array2.push(array);
console.log(array2);
// [ 4, 5, 6, [ 1, 2, 3 ] ]

array3.push(...array);
console.log(array3);
// [ 7, 8, 9, 1, 2, 3 ]

通常は配列は配列のままで渡されるが、スプレッド演算子を使うことで、配列としてではなく、その個々の中身を渡すことが可能になる。

これとは逆に、値を受け取る側でスプレッド演算子を使うことも出来る。
この場合は、該当する複数の値を、一つの配列として受け取ることが出来る。
具体的なケースとしては、分割代入での使用。

let [a,b,...spread] = [1,2,97,98,99];

console.log(a); // 1
console.log(b); // 2
console.log(spread);    // [ 97, 98, 99 ]