ES2015を学ぶ

# はじめに
Vue、React、AngularなどのモダンJSを学ぶ上で、まずはJavaScript（以後JS）の基礎を理解する必要があると思います。
自分もReactを勉強しようと思った矢先、Reactの記法の前にJSの基本を理解できていないと気づき、改めて勉強した際の備忘録です。
ReactでもES2015(ES6)の記法は結構出てきますのでモダンJSを始めようという方は、是非勉強しましょう。
他にもQiita内でES2015(ES6)について詳しく書かれている記事があると思いますので、気になった方は探してみてください。

## ES2015とは
ESとはECMAScriptの略で、JSの標準化を行っているECMA（European Computer Manufacturers Association）が定義しているものとなります。
`2015`は西暦を指しており、2015年に発表されたECMAScriptという意味合いになります。
ECMAScript 6th Editionの意味合いでES6と呼ばれることもあります。
※ES2015以後は西暦の方が正式名称となっています。

このES2015はjavaScriptの大きな転換期であり、様々な便利機能や構文が追加されていますので、次項でいくつか取り上げます。


## ES2015(ES6) の新機能について

### 実際に動かす場合

実際に手で動かしてみたい場合は、codesandboxなどを用いて試してみるのがお勧めです。

https://codesandbox.io/


## let, constについて

これらは`var`と同じくJS内で変数の使用開始を定義する際に用いられます。
`let`は`var`と同じく変数宣言、`const`は定数宣言時に使います。

`var`の挙動

```
// 変数を定義
var val = "var変数";
console.log(val); 

// var変数は上書きが可能です
val = "上書きしたvar変数";
console.log(val); 

// var変数は再宣言も可能
var val = "再宣言したvar変数";
console.log(val);　
```


`let`の挙動
```
// letで変数を定義
let val = "let変数";
console.log(val);

// 上書きは可能
val = "let変数を上書き";
console.log(val);

// 再宣言は不可
let val = "letを再宣言不可能";
console.log(val);

// ブロック内でだけ有効なのでfor文などで安全に使用できる
for (let i = 0; i < 10; i++) {
  console.log(i);
}
```


`const`の挙動

```
// constで変数を定義
const val = "const変数";
console.log(val);

// constは上書き不可
val = "const変数は上書き不可"; //　TypeErrorが出ると思います

const val = "const変数を再宣言"; // こちらもすでに変数が存在している旨のエラーが出ると思います
```

`var`は自由度が高いですが、誤った値を代入してしまったり、意図せぬ再定義をしてしまうこともあるとおもいますので、基本は`let`か`const`を使用することになると思います。
用途に合わせて使い分けてください。

・おまけ

constで定義した変数は、再代入が不可能と説明しましたが、constで定義された配列やオブジェクトは変更が可能です。

```
// constで定義した配列のプロパティは変更が可能
const arr = ["1", "2"];
arr[0] = "3";
arr.push("4");
console.log(arr);

// constで定義したオブジェクトのプロパティは変更が可能
const obj = {
   name: "tarou",
   age: 20,
};
obj.name = "karnel";
obj.gender = "Male";
console.log(obj);
```

## テンプレート文字列について

ES2015以前は文字列内に変数を挿入する場合、`+`を用いて挿入していました。
文字列をダブルクォーテーション(")の代わりに、バッククォート(`) で囲むことでテンプレート文字列が使用でき、`+`で結合する必要がなくなります。

### 従来（ES2015以前）

```
const name = "tarou";
const age = 20;

const selfIntroduction = "私の名前は" + name + "です。年齢は" + age + "際です。"; 
console.log(selfIntroduction); //「私の名前はtarouです。年齢は20歳です。」
```

### テンプレート文字列

```
const name = "tarou";
const age = 20;

const selfIntroduction =  `私の名前は${name}です。年齢は${age}歳です。`; 
console.log(selfIntroduction); //「私の名前はtarouです。年齢は20歳です。」
```

`+`がなくなる分コードがスッキリして見えます。


## アロー関数について

関数を定義する際、functionの代わりに=>を用いて関数を定義することができます。

アロー関数のメリット
- 関数定義を短く書くことができる
- thisを使い分けられる

### 従来（ES2015以前）

```
// functionを用いて関数を定義
function testFunc(str) {
   return str;
}
console.log(testFunc("従来の関数です。"));
```

### アロー関数

```
// アロー関数
const testFunc = (str) => {
   return str;
};
console.log(testFunc("アロー関数です。"));

// 中身の処理が1行でreturnできる場合{}を諸略できる
const testFunc =　(arg1, arg2) => arg1 + arg2

// 引数が1つの時は、() を省略できる
arg1 => { return arg1 + 1; }

// 逆に引数が0個の場合は ()を記述する必要がある
() => { return true; }
```

### thisの扱いについて
```
function MyClass() {
  window.setTimeout(function() { console.log(this) }, 1000); // Window オブジェクト
  window.setTimeout(() => { console.log(this) }, 1000);      // MyClass オブジェクト
}
```

returnや{}を省略できたりと書き方が様々なので、チームで開発する際には、ここらは統一した方がいいかもしれないですね。

## 分割代入

配列などの複数の値を、まとめて変数に格納できる機能になります。

```
// 配列
const arr = [1,2];
const { a, b } = arr; // aに「1」が、bに「2」が代入される

// オブジェクト
const myProfile = {
   name: "yamada",
   age: 20,
};
// 変数名とkeyが一致
const { name, age } = myProfile; // nameに「yamada」が、ageに「20」が代入される
// 変数名とkeyが異なる
const { name: namae, age: toshi } = myProfile; // namaeに「yamada」が、toshiに「20」が代入される
```

## スプレッド構文について

定義された配列に ...を付けると、その配列を展開して処理してくれます。
配列のコピーする際に、変数に入った配列をそのまま渡すと配列のインスタンスが共有されますが、
スプレッド構文を用いると、別のインスタンスとなるので元の配列に影響を与えずコピーすることが可能です。
様々な用途に使えるのでとても便利な構文です。

```
const numArr = [1, 2];
console.log(numArr); //  [1, 2]
console.log(...numArr);　// 1 2

// 順々に値を引数へ渡す　
const sumFunc = (num1, num2) => console.log(num1 + num2);
sumFunc(numArr[0], numArr[1]); // 3
sumFunc(...numArr); // 3

// 残りをまとめて代入
const numArr2 = [1, 2, 3, 4, 5];
const [num1, num2, ...arr3] = arr2;
console.log(num1); // 1
console.log(num2); // 2
console.log(arr3); // [3,4,5]

// 配列のコピー
const arr1 = [10, 20];
const arr2 = [30, 40];

// arr4をそのまま入れると同じ配列のインスタンスが使用される。
const arr3 = arr1;
arr3[0] = 100;
console.log(arr1); // [100, 20]
console.log(arr3); // [100, 20]

// スプレッド構文で元のインスタンスとは違う形でコピー可
const arr4 = [...arr2];
arr4[0] = 100;
console.log(arr2); // [30,40]
console.log(arr4); // [100,40]
```

## デフォルト値について

関数の引数にデフォルトの値を指定できます。
引数なしで呼び出された時は、デフォルト値を使用して関数を実行します。

```
const helloFunc = (name = "gest") => console.log(`こんにちは!${name}さん!`);
// 引数あり
helloFunc("yamada");
// 引数なし
helloFunc();
```

## mapやfilterを使った配列の処理について

配列に入っている値を順々に取り出して何らかの処理していく場合、forの代わりにmapやfilterを用いることができる。
mapは第1引数にvalueが入り、第2引数に要素のインデックスが入る。
filterは条件に合う値をreturnする。

```
const nameArr = ["佐藤", "田中", "山田"];
// forで回す場合
for (let index = 0; index < nameArr.length; index++) {
   console.log(`出席番号${index + 1}番は${nameArr[index]}です。`);
}

// mapで回す場合
nameArr.map((name, index) => {
  return console.log(`出席番号${index + 1}番は${name}です。`);
});

// filterで回す場合
const newNameArr = nameArr.filter((name, index) => {
   return index % 2 === 1;
});
console.log(newNameArr); // ["田中"]
```


## 終わりに
本記事には記載できていない機能がありますが、もしそちらが気になった方は参考記事を見てみてください。
今回はES2015（reactで頻出する部分）にフォーカスしておりますが、ES2015以降もどんどん新しい機能が追加されているので、今後はそちらもまとめられたらと思っています。
モダンJSにおいては、Babelによるトランスパイルの必要性などが出てきて面倒な反面、記法はどんどん便利になっていっているので覚えておいて損はないと思いました。
今後もフロントの勉強を頑張ってみようと思います。

## 参考記事
- [モダンJavaScriptの基礎から始める挫折しないためのReact入門](https://www.udemy.com/course/modern_javascipt_react_beginner/)
- [とほほのWWW入門](https://www.tohoho-web.com/js/what.htm)
- [Learn ES2015](https://babeljs.io/docs/learn/#ecmascript-2015-features-promises)