【JS / TS】Hooks がわからんのではない、分割代入をわかっていないだけ（配列編）

## 0.はじめに

分割代入の第2段の記事になります。

今回は、配列編の記事となります。

 [オブジェクト編](https://qiita.com/daishiman/items/5acf803f252b82f970fe) の記事も見て頂けると、うれしいです。

オブジェクト編をご覧になられた方は、最後の[配列の中の一部のみ使用したいとき](https://qiita.com/daishiman/items/324dcc0eae72eb6b13cf#%E9%85%8D%E5%88%97%E3%81%AE%E4%B8%AD%E3%81%AE%E4%B8%80%E9%83%A8%E3%81%AE%E3%81%BF%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E3%81%84%E3%81%A8%E3%81%8D)以外は、  
似た内容を記述しているので ~~飛ばして~~ **流し読み** して頂ければです。

間違って解釈している所ありましたら、ご指摘いただけますと幸いです。

## 1.この記事を読んだら、できるようになること

:::note info

「分割代入まじわからん」を克服できます。

下記の分割代入を理解できます。

- オブジェクトの分割代入
- **配列の分割代入 ← 今回はここ**
- 複雑な分割代入

:::

最終的には、こんな分割代入を理解できるようになります。

```ts:
const　user: User =
{
	nickname: userName = '名無し',
	age = 132,
	programmingSkills: {
		frontEnd: [
			[firstFrontEndLanguage, ...otherFrontEndLanguage],
			[firstFrontEndFW, ...otherFrontEndFW]
		],
		backEnd: [
			[firstBackEndLanguage, ...otherBackEndLanguage],
			[firstBackEndFW, ...otherBackEndFW]
		],
		infra
	}
} = user;
```

記事が長くなりそうなので、分割代入の記事を分割して書きます😏  
今回は、**分割代入の配列編**になります。

## 2.目次


[0. はじめに](https://qiita.com/daishiman/items/324dcc0eae72eb6b13cf#0%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB)  
[1. この記事を読んだら、できるようになること](https://qiita.com/daishiman/items/324dcc0eae72eb6b13cf#1%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%82%92%E8%AA%AD%E3%82%93%E3%81%A0%E3%82%89%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%93%E3%81%A8)  
[2. 目次](https://qiita.com/daishiman/items/324dcc0eae72eb6b13cf#2%E7%9B%AE%E6%AC%A1)  
[3. 環境](https://qiita.com/daishiman/items/324dcc0eae72eb6b13cf#3%E7%92%B0%E5%A2%83)  
[4. 分割代入とは](https://qiita.com/daishiman/items/5acf803f252b82f970fe#3%E5%88%86%E5%89%B2%E4%BB%A3%E5%85%A5%E3%81%A8%E3%81%AF)  
[5. オブジェクトの分割代入](https://qiita.com/daishiman/items/5acf803f252b82f970fe#5%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E5%88%86%E5%89%B2%E4%BB%A3%E5%85%A5)  
**[6. 配列の分割代入](https://qiita.com/daishiman/items/324dcc0eae72eb6b13cf#6%E9%85%8D%E5%88%97%E3%81%AE%E5%88%86%E5%89%B2%E4%BB%A3%E5%85%A5)  ← 今回はここ**  
[7. 複雑な分割代入](https://qiita.com/daishiman/items/d382279a2a6cae3ea1aa#7-%E8%A4%87%E9%9B%91%E3%81%AA%E5%88%86%E5%89%B2%E4%BB%A3%E5%85%A5)  
 

## 3.環境

- TypeScript: 4.7.4



## 6.配列の分割代入

### 6.1.配列の分割代入

下記が配列の分割代入となります。


```ts:
// 配列の分割代入
const [firstSkill, secondSkill] = programmingSkills;
```

これがどのような意味なのかを説明していきます。

#### 6.1.1.使用する配列

下記の配列を使用して、配列の分割代入の挙動を確認したいと思います。

```ts:
const programmingSkills: string[] = ['JavaScript', 'TypeScript'];
```

#### 6.1.2.分割代入で記述

配列の分割代入で記述すると、

```ts:
const [firstSkill, secondSkill] = programmingSkills;

// 実行
console.log(firstSkill);  // JavaScript
console.log(secondSkill); // TypeScript
```


なぜ、`firstSkill` を実行すると `JavaScript` が返ってくる理由がわかりませんでした。

#### 6.1.3.分割代入を使用しないで記述

上記のコードを理解するために、[オブジェクト編](https://qiita.com/daishiman/items/5acf803f252b82f970fe#%E5%88%86%E5%89%B2%E4%BB%A3%E5%85%A5%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%AA%E3%81%84%E3%81%A7%E8%A8%98%E8%BF%B0)のとき同様に、  
分割代入を使わずに変数定義を行います。

```ts
const firstSkill  = programmingSkills[0];
const secondSkill = programmingSkills[1];

// 実行
console.log(firstSkill);  // JavaScript
console.log(secondSkill); // TypeScript
```

オブジェクトの分割代入は、  
オブジェクトの **プロパティ** を指定して変数に入れていましたが、  
**配列はプロパティを持っていません。**

代わりに配列の要素番号を指定して、変数に代入します。  
これが、オブジェクトの分割代入と異なる点です。

なので、

- `firstSkill`  変数の中に、配列の `progamingSlills` の **０** 番目の要素を代入する
- `secondSkill` 変数の中に、配列の `progamingSlills` の **1** 番目の要素を代入する

という意味になります。


つまり、

```ts
const [firstSkill, secondSkill] = programmingSkills;
```

というのは、

```ts:
const firstSkill  = programmingSkills[0];
const secondSkill = programmingSkills[1];
```

を省略して記述しています。

:::note info

配列の分割代入は

- 左辺に`[]`の中に変数を、右に使用する配列を記述する
- 複数の配列の変数定義を省略できる
- 取りだしたい要素番号の記述を省略できる

:::


### 6.2.配列の中に配列がネストした分割代入

次に、配列の中に配列がネストしている場合が、どのように記述をするかを見ていきたいと思います。

#### 6.2.1.使用する配列

下記の配列を用いたいと思います。
（例としてはあまりよくかもしれませんが、ご了承くださいm(_ _)m）

```ts:
const programmingSkills: Array<Array<string>> = [
	['JavaScript', 'TypeScript'],
	['PHP', 'Ruby']
];
```

#### 6.2.2.分割代入で記述

```ts:
const [
  [frontFirstSkill, frontSecondSkill],
  [backFirstSkill, backSecondSkill]
] = programmingSkills;

// 実行
console.log(frontFirstSkill);  // JavaScript
console.log(frontSecondSkill); // TypeScript
console.log(backFirstSkill);   // PHP
console.log(backSecondSkill);  // Ruby
```

今までと同じように、分割代入を用いないで記述してみます。

#### 6.2.3.分割代入を使用しないで記述

```ts:
const frontFirstSkill  = programmingSkills[0][0];
// ・・・省略・・・
const backSecondSkill  = programmingSkills[1][1];

// 実行
console.log(frontFirstSkill);  // JavaScript
// ・・・省略・・・
console.log(backSecondSkill);  // Ruby
```

配列の中に配列がネストしているので、
- `frontFirstSkill`は、変数 `programmingSkills` の **0** 番目の **0** 番目の要素
・・・略・・・
- `backSecondSkill` は、変数 `programmingSkills` の **１** 番目の **1** 番目要素

となります。


~~これって、使うことあるんかなと思いながら記事を書いていますwww~~
皆さんは、配列のネストってどんな時に、使われていますか？
教えて頂けますと幸いですm(_ _)m


### 6.3.配列の中の一部のみ使用したいとき

次に、配列の中の**一部分の要素**を変数定義して使いたい時があるかと思います。

どういうことかといいますと、

```ts:
const programmingSkills: Array<Array<string>> = [
	['JavaScript', 'TypeScript', 'React', 'Vue'],
	['PHP', 'Ruby', 'Java', 'C++']
];
```


のうち、`JavaScript`, `TypeScript`, `Vue`, `PHP` のみ変数定義したいときとかです。

このようなときは、下記のような書き方をします。

```ts:
const [
  [frontFirstSkill, frontThirdSkill, , frontForthSkill],
  [backFirstSkill]
] = programmingSkills;
```

オブジェクトのときと異なります。（オブジェクトのときの書き方は[こちら](https://qiita.com/daishiman/items/5acf803f252b82f970fe#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E4%B8%AD%E3%81%AE%E4%B8%80%E9%83%A8%E3%81%AE%E3%81%BF%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E3%81%84%E3%81%A8%E3%81%8D)）

:::note info
配列の要素をスキップする時は、該当の要素の箇所を **空白** にします。
**ある要素以降**を変数代入しないときは、**空白も省略**して記述することができます。

:::


ちなみに、全ての要素を変数代入したいときは、

```ts:
const [
	[frontFirstSkill, frontSecondSkill, frontThirdSkill, frontForthSkill],
	[backFirstSkill, backSecondSkill, backThirdSkill, backForthSkill]
] = programmingSkills;
```

このように記述します。

`frontThirdSkill` の部分を**空白**、  
`backSecondSkill, backThirdSkill, backForthSkill` の部分を**空白も省略**していることがわかるかと思います。

### 6.4.デフォルト値

分割代入には、デフォルト値を指定することができます。


#### 6.4.1.使用するオブジェクト

下記のような **空の配列** があったとします。

```ts:
const programmingSkills: Array<string | undefined> = [];
```

#### 6.4.2.分割代入で記述

```ts:
const [firstSkill, secondSkill] = programmingSkills;

// 実行
console.log(firstSkill);  // undefined
console.log(secondSkill); // undefined

```

当たり前ですが、空の配列となるので、各それぞれ、**undefined** という結果が返ってきます。


#### 6.4.3.デフォルト値の設定

未定義のときに、デフォルト値が入っていると便利なときがあります。

例えば、`progammingSlills` が空のときは、**未経験** をデフォルトで入って欲しいなどです。

デフォルト値を設定したいときは、下記のように書くことができます。

```ts:
const [firstSkill = '未経験', secondSkill] = programmingSkills;

// 実行
console.log(firstSkill);  // 未経験
console.log(secondSkill); // undefined
```

:::note info

`firstSlill = '未経験'` のように  
**`[変数 = デフォルト値] = 配列;`**

と記述するとデフォルト値を設定することができます。

:::

:::note alert

注意点  
デフォルト値を設定するときは、**undefined** の定義が必要です。  
これは、デフォルト値が入る前に、**undefined** で弾かれてしまうからです。

:::


### 6.5.まとめ

オブジェクトの分割代入同様、  
分割代入を使用しない記述と比較すると理解しやすいかと思います。

形で覚えるのではなく、どのような動きをしているのかを理解することが重要ですね。

次回は、実践的なオブジェクトと配列の混合の分割代入についてまとめたいと思います。

併せて他の記事も読んでいただけると嬉しいです🙇‍♂️

https://qiita.com/daishiman/items/5acf803f252b82f970fe

https://qiita.com/daishiman/items/d382279a2a6cae3ea1aa


## 参考
[書籍：プロを目指す人のためのTypeScript入門　鈴木僚太［著］](https://twitter.com/uhyo_/status/1517158176365641729?s=20&t=5jZBSZVbLrAsgkCUruO7Ig)