【JS初心者向け】変数の使い分け（let、const、var）

アウトプット用の記事です！  
間違ってる点があったらごめんなさい<(_ _)>

# 変数の使い分け

JavaScriptの変数は、最もよく使われているだろうlet、constの２つ、そして最近ではあまり使われることがなくなったvarを加えた合計３つの変数あります。　　
この３つの変数の使い分けで困った人も多いと思います。本記事ではその使い分けについて解説していきます。

# それぞれの変数の特徴
特徴は以下の表のようになります。

|       | 再代入 | 再宣言 | スコープ |ホイスティング<br>（変数の巻き上げ）| 
| ----- | ------ | ------ | -------- | -------------------------------- | 
| let   | 〇     | ×      | ブロック | ×                                | 
| const | ×      | ×      | ブロック | ×                                | 
| var   | 〇     | 〇     | 関数     | 〇                               | 

では各項目についてそれぞれ解説していきます。

## 再代入
再代入とは**一度宣言した変数に再度値を代入しなおすこと**です。

#### 例
```
let num = 3; //変数の宣言
num = 5; //変数に再代入
```
この変数の再代入はletとvarは正常に動作します。しかしconstで宣言した場合、再代入を行うとエラーが発生します。  
変数の値を変えたくない場合、constを使うと良いでしょう。**letやvarを使うと再代入を行ってしますかもしれません**。

## 再宣言
再宣言とは**一度宣言した変数をもう一度宣言してしまうこと**です。

####  例
```
var num = 3; //変数の宣言
var num = 0; //変数の再宣言
```
再宣言はvarでのみ正常に動作します。letやconstで再宣言をしてしまうとエラーが発生します。

## スコープ
スコープとは**宣言した変数が使用できる範囲のこと**です。
今回の変数のお話では。**ブロック**と**関数**の２種類のスコープがでてきます。

### ブロック
ブロックとは**中括弧｛｝で区切られた範囲のこと**です。

#### 例
```
{
ーーーーーーーーーーーーーー
ここがブロックのスコープです
ーーーーーーーーーーーーーー
}
```
letとconstのスコープはブロックです。つまりあるブロック内でこれら２つの変数を用いて宣言された変数は、**そのブロック内でしか使用できません**。ブロックの外でその変数を用いようとするとエラーが発生します。
```
let a = 0;
function test() {
    let b = 1;

    console.log(a); // 0
    console.log(b); // 1
}

console.log(a); // 0
console.log(b); // エラー、原因はブロックの範囲内を出てしまったためです。
```

### 関数
関数とは**スコープが関数全体の範囲のこと**です。

#### 例
```
function test(){
ーーーーーーーーーーーー
ここが関数のスコープです
ーーーーーーーーーーーー
}
```
３つの変数のうちvarのみが関数のスコープです。具体的な説明はブロックとほとんど同じです。ブロックの範囲を関数全体に広げたものだと覚えておいてください。

```
var a = 0;

function test() {
    var b = 1;

    console.log(a); // 0
    console.log(b); // 1
}

console.log(a); // 0
console.log(b); // エラー、原因は関数のスコープから出てしまったため
```

#### 使い分け
基本的にはvarではなく、letとconstを使いましょう。
理由はvarを使用すると以下のようになってしまうからです。
```
var a = 0;

function test() {
    var b = 1;

    if (true) {
        var c = 2;

        console.log(a); // 0
        console.log(b); // 1
        console.log(c); // 2;
    }

    console.log(a); // 0
    console.log(b); // 1
    console.log(c); // 2
}

console.log(a); // 0
console.log(b); // エラー、原因は関数のスコープから出てしまったため
console.log(c); // エラー、原因は関数のスコープから出てしまったため
```

このように**宣言した同じ関数内ならどこでも使用できてしまう**のです。
これのどこが問題かというと、もしif内のみで使用したい変数があったとします。ですがvarで変数を宣言してしまうと、関数全体がスコープになってしまいますのでif内のみで使用することはできません。
しかしletやconstを用いると、
```
const a = 0;

function test() {
    const b = 1;

    if (true) {
        const c = 2;

        console.log(a); // 0
        console.log(b); // 1
        console.log(c); // 2;
    }

    console.log(a); // 0
    console.log(b); // 1
    console.log(c); // エラー、原因は変数cがifのブロックスコープから出ているため
}

console.log(a); // 0
console.log(b); // エラー、原因は変数bが関数のスコープから出てしまったため
console.log(c); // エラー、原因は変数cが関数のスコープから出てしまったため
```
このようにletやconstだとスコープを限定できるため、より使い勝手がよくなります。

## ホイスティング（変数の巻き上げ）
ホイスティングとは**変数を宣言する前に、変数に値を代入してしまうこと**です。またホイスティングは関数の巻き上げとも呼ばれます。

### 例
```
a = 100;
var a = 100;
```
ホイスティングはvarでのみ成り立ち、letとconstではエラーが発生します。このような現象はコーティングする上でエラーを招く原因になりかねないので、varではなくletとconstを使用しましょう。

# まとめ
以上、それぞれの変数の特徴を説明しました。varは古い変数で、現在主流なのはletとconstです。varよりもletとconstが良いことも特徴と一緒に説明しました。  
基本的にはletとconstを使用しましょう。