【Javascript】Rest pattern/parameters（残余パターン/引数）について

# 初めに
Spread operator(スプレッド構文）と形は似ていますが、真逆のことをするRest pattern/parametersについて学習した内容を書いてみました。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。

#Rest pattern/parameters（残余パターン/引数）とは
MDNの公式ドキュメントには以下のように説明しています。
> 残余引数構文により、不定数の引数を配列として表すことができます。

要するに要素や引数を凝縮（condense)し配列として返します。要素を展開するスプレッド構文と正反対のことをします。

前回の記事：
https://qiita.com/redrabbit1104/items/374fc9cc0c0408f51e66

# 見分け方
残余パターン/引数はスプレッド構文と非常に似ていますが、「=」の左側にあるか右側にあるかでどちらなのか判断できます。

①スプレッド構文

```javascript
//スプレッド構文は「=」の右側

const testNumber = [100, 99, 98, ...[2, 1]];
console.log(testNumber);
```
testNumberの中の配列[2, 1]が展開されている。
![スクリーンショット 2021-05-18 7.42.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/f19f97ca-c3fc-47f7-9c7a-43603e1e1aa0.png)

②残余パターン

```javascript
//残余パターンは「=」に左側

const [a, b, ...rests] = [100, 99, 98, 2, 1];
console.log(a, b, rests);
```
配列の要素98,2,1がパッキングされ、配列の[98, 21, 1]になっている。
![スクリーンショット 2021-05-18 7.47.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/3e214030-1720-14b6-f1ac-3085aee4eafe.png)

# 分割代入の時に使われる(配列）
配列の要素を変数に代入する分割代入の場合を考えます。2つの配列の要素をaとbの変数に格納し、残りはrests(名前はなんでもいいです）という配列の形をした変数に入れることができます。

```javascript
const park = {
　//中略
  trees: ["ヒノキ", "竹", "松", "杉", "イチョウ"],
  flowers: ["薔薇", "桜", "朝顔", "ひまわり"],
  //中略
};

const [a, b, ...rests] = [...park.trees, ...park.flowers];
console.log(a, b, rests);
```
変数aとbにはヒノキと竹が保存され、restsには配列の形でtreesとflowers、両方の配列の要素からヒノキと竹を除いた残りの要素が格納されていることが分かります。
![スクリーンショット 2021-05-18 8.02.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/04619540-756b-18b7-4c1f-1db4a05c57c0.png)
残余パターンは必ず要素の最後になります。
例えば、先ほどの例で...restsの右側にcという変数を入れたとします。

```javascript
const [a, b, ...rests, c] = [...park.trees, ...park.flowers];
console.log(a, b, c, rests);
```
Rest element(残余要素）は最後でなければならないとエラーが出てしまします。
![スクリーンショット 2021-05-18 8.09.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/bc09130e-152d-66a0-f6cc-dda7d7013a1b.png)

前回の記事：
https://qiita.com/redrabbit1104/items/3ba4783c658ebfa624a0
# 分割代入の時に使われる(オブジェクト）
オブジェクトも同じように分割代入の残りとして残余パターンを使うことができます。

```javascript
const park = {
   //中略
  temp: {
    mon: {
      morning: 12,
      evening: 5,
    },
    tue: {
      morning: 15,
      evening: 7,
    },
    wed: {
      morning: 13,
      evening: 4,
    },
  },
};

const { mon, ...rests } = park.temp;
console.log(rests);
```
結果はmonを除いた残りのtueとwedが表示されます。
![スクリーンショット 2021-05-18 8.26.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/49568471-9d44-a842-fe49-8a79518a96cb.png)

前回の記事：
https://qiita.com/redrabbit1104/items/c8eb9d88e238ec0b59fd

# 関数の場合
関数では残余引数の場合を考えられます。例えば、引数の数を柔軟に対応できます。

```javascript
const park = {
  test: function (...rests) {
    console.log(rests);
  },
};
park.test(1, 2, 3, 4, 5, 6);
```
この場合残余引数restsは配列の形になっていることが分かります。これは残余引数は要素を配列としてパッキングするからです。
![スクリーンショット 2021-05-18 8.53.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/caf050ec-0743-f754-8e60-ea4f1a0442d9.png)
残余引数が配列ということが分かったので、残余引数を使って数字を足し算してみました。

```javascript
park = {
  //中略
  sumPrice: function (...rests) {
    let sum = 0;
    for (let i = 0; i < rests.length; i++) {
      sum += rests[i];
    }
    console.log(sum);
  },
};
park.sumPrice(1, 2, 3, 4, 5, 6);
```
1から6の値の合計が表示されました。
![スクリーンショット 2021-05-18 9.01.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/ef7f8fb2-e810-2d89-d341-602b790ce987.png)
sumPriceの引数を配列にすることもできます。

```javascript
const numArr = [4, 5, 33, 2];
park.sumPrice(...numArr);
```
このように配列numArrの合計値が表示されます。
![スクリーンショット 2021-05-18 9.08.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/358164b5-2c45-f5f5-19e8-0c15e4410123.png)
numArrをスプレッド構文として展開(unpacking)し、関数sumPriceで残余引数として配列にパッキングし直して合計値を求めています。
引数を数字列として入れることもできますし、配列にして入れることもできるので非常に便利です。

# 参考サイト

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/rest_parameters