[Javascript] スプレッド構文の解説

## はじめに
こんにちは! プログラミング学習中のタイソンです！
今回はES6で追加されたスプレッド構文について学んだことを、分かり易さ重視で解説していこうと思います。わかりにくいところ、間違っているところなどがございましたら、お気軽にご指摘ください！
## スプレッド構文とは
「...」
このようなドットが３つ並んだコードを皆さんは見たことがあるでしょうか。この３つのドットをスプレッド構文と言います。このスプレッド構文を一言で表すと

**順番に処理して展開する**

というものです。

この言葉だけではあんまりピンと来ないですよね。
大丈夫です！コードでわかりやすく解説していきます！

## 配列の展開
```javascript
const arr1 = [1,2];
console.log(arr1);
```
このような配列があるとします。この配列arr1の中身をconsole.log()で見てみましょう。
![arr1の中身](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/96b40cdd-cf18-22bb-cd97-d679d00bc049.png)
もちろんこのような結果になります。次はスプレッド構文を使って配列の中身を見てみましょう。

```javascript
const arr1 = [1,2];
//スプレッド構文で配列の中身をみる↓
console.log(...arr1);
```
![arr2の中身](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/1213ffb6-edb7-ac1f-7e54-316d517a72d6.png)
先ほどはconsole.logの結果が配列だったのに対して、今回は実際の1と２という値になっていることがわかります。

このようにドットを３つ書いてその後に配列を指定すると、**配列の中身を順番に処理して展開**します。

ちょっと複雑でわかりにくいですよね。もう少し分かり易い例で解説していきます。

```javascript
//配列の作成↓
const arr1 = [1,2];
//アロー関数の作成↓
const sumFunc = (num1, num2) => console.log(num1 + num2);
//実引数に配列の値を指定↓
sumFunc(arr1[0], arr1[1]);
```
このような配列とアロー関数を作成して、コンソールで結果をみてみましょう。

![コンソールの結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/b1a14624-0e5d-e154-80eb-3dceec74f6d6.png)
このような結果になりました。
次は同じ式にスプレッド構文を使って引数を渡していこうと思います。

```javascript
const arr1 = [1,2];
const sumFunc = (num1, num2) => console.log(num1 + num2);
sumFunc(...arr1);
```
結果はこのようになります。
![コンソールの結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/5ad681d8-79f4-30f6-b589-968d33bfb09d.png)
先ほどと同じ結果になりましたね。先ほどの記述と、このスプレッド関数を使った例は同じ動きをしているということになります。

配列に対してドットが３つあったら、
**順番に処理して展開**
と頭の中で変換してください。

## 配列をひとつにまとめる
前の章はスプレッド構文の配列の展開についてでしたが、次は配列をひとつにまとめるというスプレッド構文の使い方について解説しようかと思います。

```javascript
//配列を用意↓
const arr2 = [1, 2, 3, 4, 5];
//配列をスプレッド構文を使って分割代入↓
const [num1, num2, ...arr3] = arr2;
```
このような配列を用意し、分割代入していきます。
console.log()でnum1とnum2の値の中身を見てみましょう。

分割代入が何かわからない方はこちらの記事を読んでください。↓

https://qiita.com/TTTaison/items/c55afef6dbb9183d6efc

```javascript
const arr2 = [1, 2, 3, 4, 5];
const [num1, num2, ...arr3] = arr2;

console.log(num1);
console.log(num2);
```
![コンソール２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/261461ef-5888-8eac-75f1-20e02237df94.png)
このような結果になりました。次にarr3の中身をconsole.logで見てみましょう。

![コンソール2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/b6ec5aa7-9e4a-2e63-57a3-baa7ff32698e.png)

1と2以外の数字が配列としてまとめられていました。このようにスプレッド構文は配列をまとめることもできるのです。

## 配列のコピーや結合
次は配列のコピーや結合について解説していきます。とても大事なところなのでしっかり勉強していきましょう。

```javascript
const arr4 = [10, 20];

const arr5 = [30, 40];
```
まずこのような２つの配列を用意します。そして新しくarr6という配列をスプレッド構文で用意します。

```javascript
const arr4 = [10, 20];

const arr5 = [30, 40];

const arr6 = [...arr4];
```
console.log(arr6)で、配列arr6の中身を見てみましょう。
![コンソール２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/386dc074-d7e1-5f63-4417-1541303563ce.png)
このようにarr4の中身がコピーされました。このようにスプレッド構文は配列のコピーにも使うことができます。

次にこれの応用として、スプレッド構文の結合について見ていこうと思います。先ほどのコードを以下のように変更します。

```javascript
const arr4 = [10,20];

const arr5 = [30,40];

const arr6 = [...arr4, ...arr5];
console.log(arr6);
```
この配列arr6の中身はどうなっているのでしょうか。console.logで見てみましょう。
![コンソール２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/83ebae00-b168-d713-39e9-a1f06f8c1ee6.png)
配列arr4とarr5の中身が結合されましたね。
このようにスプレッド構文を使うと配列の結合も容易に行うことができます。

## 参照渡しについて
しかし配列のコピーをするだけなら、以下のように

**「配列を=でそのままコピーすればいいじゃん！」**

と思う人がいるかもしれません。

```javascript
const arr4 = [10,20];
//arr4をコピーしたarr8を定義
const arr8 = arr4;
```
console.log(arr8)の中身を見てみましょう。
![コンソール2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/d18faa61-0345-8afa-c899-65b3f311675d.png)
このようにコピーができていますね。

**しかしこれには問題があります。**

参照が引き継がれてしまっているのです。
以下の例を見てみましょう。

```javascript
const arr4 = [10,20];

const arr8 = arr4;
//arr4をコピーしたarr8の最初の値を変更する↓
arr8[0] = 100;

console.log(arr8);
console.log(arr4);
```
console.log()でarr8とarr4の中身を見て見ましょう。
![コンソール２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/d4b85342-e2aa-abbc-79d0-a1fea24646f3.png)
arr8の値だけを100に変えたつもりなのに、元のarr4の値も100に変わってしまっています。

このようなことが起こってしまうので、配列のコピーをする際はスプレッド構文を使いましょう。スプレッド構文で同じことをやってみましょう。

```javascript
const arr4 = [10,20];

const arr8 = [...arr4];

arr8[0] = 100;

console.log(arr8);
console.log(arr4);
```
console.logでarr8とarr4の中身を見てみましょう。
![コンソール２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/09dc0615-ea93-cd4d-9581-b6c5c1d9c1eb.png)
arr4の値を変えずに、arr8の値だけを変えることができました。

なぜこのようなことが起こってしまうのかは以下の記事を参考にしてください。

https://freelance-jak.com/technology/java/998/

## 最後に
いかがだったでしょうか。スプレッド構文はjavascriptだけでなく、Reactなどでも使っていくのでしっかり理解を深めておきましょう。見ていただきありがとうございました。