【React/JavaScirpt】これを知っておけば大丈夫？JavaScriptの基礎

## 背景
今月に入りReact/Next.jsを業務で使用するようになりましたがあまりにも自分がJavaScriptのことを知らなさすぎて危機感を感じたので、実際にコードを書いていく中でよく目にするものを抜粋して学んだのでアウトプットしたいと思います。

もし読者の中に、これからReactやVue.jsを触れるけれどもあまりJavaScriptの経験がないという人がいればぜひこの記事の範囲を学んでおけば慌てることはないのかなと思います。

## 変数宣言
JavaScirptで変数宣言をするには`var`,`let`,`const`の３つキーワードがあります。それぞれの違いは以下のとおりです。

再宣言は同じ変数名で再度変数宣言をすることで、再代入は同じ変数に値を再度設定し直すことです。

### const
constant(定数)という意味から再宣言、再代入ができないキーワードで、変数への再代入はバグの原因になりかねないという理由から変数に再代入をする必要がない場合はconstを使用するように推奨されています。

```javascript
const name = 'taro'
// 再宣言
const name = 'jiro' //SyntaxError:  Identifier 'name' has already been declared 

// 再代入
const name = 'taro'
name = 'jiro' // TypeError: "name" is read-only
```

### let
`let`は`const`と違い値の再代入が可能です。そのためfor文などの反復処理の途中で変数を変化させたいときなどに使用します。
```javascript
let name = 'taro'
name = 'jiro'
console.log(name) // jiro 
```
### var
`var`は変数の再宣言、再代入が可能です。
`let`や`const`で再代入や再宣言をしようとしてもエラーが発生してそれ以上処理をすることはできませんが`var`ではそれができてしまいます。そのため思わぬエラーを生む原因となってしまうため`var`の使用は避けたほうがよいでしょう。

## 分割代入
分割代入は配列やオブジェクトからプロパティを取り出して違う変数に代入する操作を簡略したものです。
例えばpersonオブジェクトがあり、そのプロパティをそれぞれ違う変数に代入したい場合以下のようにすると実現できます。
### オブジェクトの分割代入
```javascript
const beer = {
  asahi: 'スーパードライ',
  kirin: '一番搾り'
};

const asahi = beer.asahi;
const kirin = beer.kirin;
```
分割代入を使用するとこのようにスッキリ書くことができます。
```javascript
const { asahi, kirin } = beer;
console.log(asahi) // => スーパードライ
console.log(kirin) //=> 一番搾り
```
##### プロパティと異なる名前で代入する
オブジェクトから変数を取り出して、オブジェクトのプロパティとは異なる名前の変数に代入することも可能です。
このとき`:(セミコロン)`の左側がプロパティ、右側が新しく代入したい変数名とすることで定義できます。

```javascript
const mountain = {
  kanagawa: "丹沢山",
  nagano: "常念岳"
};

const { kanagawa: tanzawa, nagano: kitaAlps } = mountain;
console.log(tanzawa, kitaAlps); // 丹沢山　常念岳
```

### 配列の分割代入
配列の場合は左辺に配列のような構文で代入したい変数名を定義して、右辺に配列の入った受け取り元の変数を書きます。
こうすることで元の配列の入った変数のインデックスに対応する順番で左辺の変数に代入されていきます。
以下の例であればindexが`0`の`Dragons`は左辺のindexが`0`の`nagoya`に、indexが`1`の`Baystars`は`yokohama`に・・・といった感じで代入されていきます。
```javascript
const centralLeage = ["Dragons", "Baystars", "Carp"];

const [nagoya, yokohama, hirosima] = centralLeage;
console.log(nagoya, yokohama, hirosima);
// => Dragons Baystars Carp 
```
##### 変数の数と配列の要素の数が合わないとき
配列内の要素が、左辺に定義した変数よりも多い場合はどうなるでしょうか。
この場合はまず右辺の元の配列の要素の数だけ左辺の新しい変数へと代入されます。
以下の例であれば元の配列の要素の数は2つなので`nagoya`と`yokohama`へ値が代入されます。
そして余った変数（この場合であれば`hiroshima`）の値については`undefined`となります。
つまり右辺の要素の数がNで、左辺に指定された変数の数がNよりも大きい場合左辺の始めからN個に代入されて、残りの変数はundefinedの値が設定されるということになります。
```javascript
const centralLeage = ["Dragons", "Baystars"];

const [nagoya, yokohama, hirosima] = centralLeage;
console.log(nagoya, yokohama, hirosima);
// => Dragons Baystars undefined 
```

## アロー関数
アロー関数は無名関数を記述しやすくした省略記法です。
通常無名関数を定義するためにはこのように書く必要があります。
```javascript
const func = function (a) {
  return a + 100;
};
```
これをアロー関数を用いて書くとこのように書くことができます。
functionを消して（）と{}の間に`=>`を配置することでアロー関数の書き方にすることができます。
```javascript
const func = （a) => {
    return a + 100;
}
```
また引数の`()`や`{}`、`return`は条件を満たしていれば省略することもできます。
```javascript
// 引数が一つの場合には()を省略できる
const func = a => {
    return a + 100;
}
// 引数が複数の場合には()は省略できない
const func = （a, b) => {
    return a + b + 100;
}
// 一行のみであれば{}は省略できる、複数行の場合は省略できない
// また一行のみであればreturnは省略できる
const func = a => a + 100;
```
また先程あった分割代入にもアロー演算子は対応しています。
配列の分割代入をアロー関数で活用するとこんな感じに使えます。
```javascript
const arry = ["Taro", 26, "Japan"];

const introduce = ([name, age, countory]) =>
  `Hello I'm ${name}. I'm ${age} years old. I'm from ${countory}.`;

console.log(introduce(arry));
// Hello I'm Taro. I'm 26 years old. I'm from Japan. 

```
オブジェクトの分割代入でも同じようにアロー演算子は使えます。
```javascript
const obj = { name: "John", age: 32, countory: "USA" };

const introduce = ({ name, age, countory }) =>
  `Hello I'm ${name}. I'm ${age} years old. I'm from ${countory}.`;

console.log(introduce(obj));
// Hello I'm John. I'm 32 years old. I'm from USA. 

```
https://qiita.com/im36-123/items/95db77d8f64609a85043

## スプレッド構文
`...`を使うことで配列やオブジェクトの要素を展開することができます。

### 配列の場合
下記のような配列があり、元の配列に要素を追加して新しい配列を作りたい場合にスプレッド構文を使うとこのように書くことができます
```javascript
const city = ["tokyo", "nagoya", "fukuoka"];

const new_city = [...city, "osaka"];

console.log(new_city); // ["tokyo", "nagoya", "fukuoka", "osaka"]
```
スプレッド構文を活用すると配列の連結もできます。
```javascript
const city1 = ["tokyo", "nagoya", "fukuoka"];

const city2 = ["sapporo", "aomori", "morioka"];

const new_city = [...city1, ...city2];

console.log(new_city);
//  ["tokyo", "nagoya", "fukuoka", "sapporo", "aomori", "morioka"]
```
また任意の位置に要素を追加することもできます。
```javascript
const city = ["tokyo", "nagoya", "fukuoka"];

const new_city = ["sapporo", ...city, "kobe"];

console.log(new_city);
// ["sapporo", "tokyo", "nagoya", "fukuoka", "kobe"]
```

### オブジェクトの場合
要素を追加して新しいオブジェクトの作成
```javascript
const city = {
  tokyo: "tokyo",
  aichi: "nagoya"
};

const new_city = { ...city, osaka: "osaka" };

console.log(new_city);
// {tokyo: "tokyo", aichi: "nagoya", osaka: "osaka"}
```
オブジェクトの連結
```javascript
const city1 = {
  tokyo: "tokyo",
  aichi: "nagoya"
};

const city2 = {
  hokkaido: "sapporo",
  aomori: "aomori"
};

const new_city = { ...city1, ...city2 };

console.log(new_city);
// {tokyo: "tokyo", aichi: "nagoya", hokkaido: "sapporo", aomori: "aomori"}
```
オブジェクトの任意の位置に追加
```javascript
const city = {
  tokyo: "tokyo",
  aichi: "nagoya"
};

const new_city = { hokkaido: "sapporo", ...city, hyogo: "kobe" };

console.log(new_city);
// {hokkaido: "sapporo", tokyo: "tokyo", aichi: "nagoya", hyogo: "kobe"}
```
https://qiita.com/FumioNonaka/items/58358a29850afd7a0f37

## 配列の処理
Arrayのメソッドはこれ以外にもめっちゃありますが、そのなかでも普段よく使うものをピックアップしてみました。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array

### map
mapメソッドは与えられた関数を配列のすべての要素に対して実行して、その結果から新たな配列を作ります。
```javascript
array.map((引数1,引数2,引数3) => {処理})
```
第１引数に現在処理中の配列の要素、第２引数に配列のインデックス、第３引数は処理を実行している配列自体が入ります。
```javascript
const numbers = [1, 2, 3, 4];

const result = numbers.map((number) => number * 2);
console.log(result); // [2, 4, 6, 8]
```
実際にアプリケーションを開発しているときではレスポンスのオブジェクトの配列を回して表示したいときなどに下記のようによく使います。
```javascript
const members = [
  { name: "一郎", age: 10 },
  { name: "次郎", age: 23 },
  { name: "三郎", age: 18 }
];

const res = members.map((member) => `${member.name}くんは${member.age}歳です`);
console.log(res); // ["一郎くんは10歳です", "次郎くんは23歳です", "三郎くんは18歳です"]
```

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map
### find
`find`メソッドは条件に一致する最初の要素を返します。次の`filter`メソッドによく似ていますが最初の要素を返すことに注意しましょう。
第１引数に現在処理中の配列の要素、第２引数に配列のインデックス、第３引数は`find`が呼び出した元の配列です。
```javascript
array.find((引数1,引数2,引数3) => {条件式})
```
#### 配列で使う場合
例えば配列`numbers`の要素の中から20より大きいものを取得するには以下のようなコードとなります。
21も条件式を満たしていますが、最初に見つかった32が返されています。
```javascript
const numbers = [13, 9, 32, 21];

const result = numbers.find((number) => number > 20);

console.log(result); // 32
```
#### オブジェクトの配列で使う場合
オブジェクトの配列にも使うことができます。
```javascript
const members = [
  { name: "一郎", age: 10 },
  { name: "次郎", age: 23 },
  { name: "三郎", age: 21 }
];

const adult = members.find((member) => member.age > 20);

console.log(adult); // {name: "次郎", age: 23}
```
#### 条件を満たさない場合の返り値
条件式を満たすものがなかった場合には`undefined`が返されます。
```javascript
const numbers = [13, 9, 19, 1];

const result = numbers.find((number) => number > 20);

console.log(result); // undefined
```

### filter
`filter`メソッドは`find`メソッドと異なり条件に一致するものを**すべて返します**
第１引数に現在処理中の配列の要素、第２引数に配列のインデックス、第３引数は`filter`が呼び出された配列です。
```javascript
array.filter((引数1,引数2,引数3) => {条件式})
```
#### 配列で使う場合
```javascript
const numbers = [13, 9, 32, 21];

const result = numbers.filter((number) => number > 20);

console.log(result);// 32,21
```
#### オブジェクトの配列で使う場合
```javascript
const members = [
  { name: "一郎", age: 10 },
  { name: "次郎", age: 23 },
  { name: "三郎", age: 21 }
];

const adult = members.filter((member) => member.age > 20);

console.log(adult); // {　name: "次郎" age:23 }, { name: "三郎" age:21 }
```
#### 条件を満たさない場合の返り値
`filter`は条件を満たす値がない場合は`空の配列`を返します。
```javascript
const numbers = [13, 9, 19, 1];

const result = numbers.filter((number) => number > 20);

console.log(result); // []
```

## 最後に
本当はまだまだたくさんありますが、とりあえずこの記事に上げたものを知っていればとりあえずコードを書くには困らないのかな？と思います。
ほんとうはPromise/Asyncも書きたかったのですが一つの記事になりそうなボリュームになりそうな感じがあるので別の機会に書こうと思います。

## その他参考
https://developer.mozilla.org/ja/

https://jsprimer.net/