はじめに
どちらも同じ演算子「...」を利用する為
混乱するかもしれないので初めに簡単に違いを説明すると。
スプレッド構文 | レスト構文 |
---|---|
展開 | 集約 |
だと個人的には考えていますです。
これを踏まえた上で詳しく見ていきましょう。
スプレッド構文とは
スプレッド構文を使うと、関数呼び出しでは 0 個以上の引数として、Array リテラルでは 0 個以上の要素として、Object リテラルでは 0 個以上の key-value のペアとして、Array や String などの iterable オブジェクトをその場で展開します。
ようするに 関数呼び出しの引数, 配列リテラル, オブジェクトリテラル に対してオブジェクトを展開出来るって事ですね。
実際にコードを書いていきます。
関数呼び出し
例 配列の中から最大値を取得したい場合
const nums = [3, 1, 4, 1, 5, 9, 2, 6];
console.log(Math.max(...nums));
// 出力 9
また、何番目の引数でも利用することができます。
const nums = [3, 1, 4, 1, 5, 9, 2, 6];
console.log(Math.max(0, ...nums, 20, 8));
// 出力 20
new演算子の引数にも使用できます。
const dateFields = [1970, 0, 1];
const d = new Date(...dateFields);
console.log(d);
//出力 Thu Jan 01 1970 00:00:00 GMT+0900 (日本標準時)
配列リテラル
例 配列を複製したい場合
let arr = [1, 2, 3];
let newArr = [...arr];
console.log(newArr);
// 出力 [1, 2, 3]
例 配列を結合したい場合
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let newArr = [...arr1, ...arr2];
console.log(newArr);
// 出力 [1, 2, 3, 4, 5, 6]
オブジェクトリテラル
例 オブジェクトを複製したい場合
const obj = {
name: 'kamijo',
age: 22
}
const newObj = {...obj};
console.log(newObj);
// 出力 {name: 'kamijo', age: 22}
レスト構文とは
スプレッド構文とは逆で
複数の要素を集約して 1 つのオブジェクトにまとめることが出来ます。
関数の引数や分割代入での不特定多数の値を配列として受け取る際に利用します。
分割代入に関してはこちら。
【JavaScript】「分割代入」について
可変長引数の関数
function outputArgs(...args) {
for(const a of args){
console.log(a);
}
}
outputArgs('a', 'b', 'c', 'd');
// 出力 a b c d
分割代入(配列)
const arr = [1, 2, 3, 4, 5];
const [a, b, ...c] = arr;
console.log(a, b, c);
// 出力 1 2 [3, 4, 5]
分割代入(オブジェクト)
const obj = { a: 1, b: 2, c: 3, x:10 };
const { x, ...props } = obj;
console.log(x);
// 出力 10
console.log(props);
// 出力 {a: 1, b: 2, c: 3}
おまけ
文字列にも使えます。
const [a, b, ...c] = 'aiueo';
console.log(a, b, c);
// 出力 a i ['u', 'e', 'o']