【Javascript基礎】基本的な変数/定数の書き方

# ◆変数とは
**「データの入れ物」**・**「データを入れる箱」** と表現されることが一般的。
基本的にこのイメージで充分。

# ◆変数宣言
## ・ 変数の宣言とは
変数の名前の登録をJavascriptに登録し、かつ、値を格納するための領域をメモリ上に確保することを指す。

## ・ 変数宣言の書き方
変数を宣言するには、以下のように **<font color="red">var</font>** 命令を使用する。
```javascript
var 変数名

var 変数名 = 初期値
/**
 * 例）
 * var number = 10;
 * 
 * var str = "Javascript";
 * 
 */
```
以下のようにカンマ区切りで複数宣言することも可能。

```javascript
var x, y;
```
初期値を設定しなかった場合、Javascriptにはデフォルトで、

**<font color="red">未定義（undefined）</font>** という時別な値が変数に割り当てられる。

## 【補足】　- 実は変数宣言は任意 -
Javascriptでは変数宣言は任意である。
具体例として、以下のようなコードは間違いではなく、問題なく機能する。
```javascript
msg = "こんにちは";
console.log(msg);

// 出力：　こんにちは
```
consoleで出力するタイミングでは、msgはvar命令で宣言をしていない。
つまり、これは変数宣言をしていないことになる。

にも関わらず処理が正常に動く理由は、
**<font color="blue">Javascriptが暗黙的に変数宣言を行ってくれるからである。</font>**

しかし、この変数宣言の省略は<font color="red">**原則として避けるべきである。**</font>

理由や具体例は、 **【番外】 -変数の参照について-** 　で記載する。

## ・ 別の変数宣言 -let-
変数宣言を行うもう一つの命令として、**<font color="red">let</font>命令**がある。
書き方は、var命令と同じ。
```javascript
let 変数名;

let 変数名 = 初期値;
```
では、どのように使い分けたら良いのか。

## ・ letは変数の重複を許可しない
まず結論として、
**<font color="red">変数宣言は基本的に　「let」　を使用する</font>** 事がおすすめ。

理由は変数名が重複した場合、letはエラーを発生してくれるから。
```javascript
let msg = "Hello";

let msg = "See you";
/**
 * Identifier 'msg' has already been declared.
 * （msg　は既に宣言されている。）
 */
```

一方varの場合、
```javascript
var msg = "Hello";

var msg = "See you";
```
エラーは発生しない。
（この場合、msgの中身は　See you　で上書きされる。）

以上のようにvar命令の宣言は、気づかないところで宣言を上書きし、予期しないバグを生む可能性がある。

よって、変数宣言は基本的に　**let**　を使用するべき。

# ◆定数宣言
**定数**　は変数と概念は同じ。違うところは、

**<font color="red">途中で中身を変更できない</font>**

という1点だけ。

## ・ 定数宣言の書き方
定数の宣言には、**<font color="red">const</font>命令を使用する。**
```javascript
const 定数名 = 値;
```
ここで注意する点は、
**<font color="red">定数宣言では、宣言時に初期値の代入も必ず行う必要がある</font>** ということ。
変数宣言時のような、宣言だけを行うことはできない。

## ・ 定数宣言のちょっとしたルール
定数宣言は宣言時に**const**命令を使用するだけで、他は変数宣言と変わりはない。
しかし定数であることを識別しやすくするよう、以下のようなルールで書くことが多い。

**<font color="blue">・全て大文字</font>**

**・<font color="blue">単語をアンダースコアで区切る</font>**

```javascript
const DEFAULT_USER_NAME = "user name";

const CONSUMPTION_TAX = 1.10;
```

※このルールは強制ではいため、「上記のルールで必ず書かなければいけない」というわけではない。


# ◆識別子の命名規則
## ・ 4つの命名規則
**識別子**とは、互いを識別・区別するために付けられた名前のこと。
Javascriptでは自由に名前を決められるが、以下の４つの規則がある。

|No  |規則   |例   |
|:-:|:-:|:-:|
|1   |1文字目は英字 or アンダースコア or ドル記号のどれか   |name, _name, $name   |
|2   |2文字目以降は、1文字目で使える文字、もしくは数字   |name1   |
|3   |変数名に含まれる英字の小文字・大文字は区別される   |name と Name は別物  |
|4   |Javascriptで意味を持つ<font color="red">予約語</font>は使用できない   |for, if, let　など   |

## ・ 予約語
Javascriptの予約語は下記サイトを確認すると良い。

https://www.javadrive.jp/javascript/ini/index5.html


## ・ 基本的は変数宣言の記法
ここでは、変数宣言で一般的に用いられる記法を紹介。
| 記法 | 概要 | 例 |
|:-|:-|:-|
| camelCase記法  | 先頭の頭文字は小文字、それ以降の頭文字は大文字  | firstName  |
| Pascal記法  | 全ての単語の頭文字は大文字  | FirstName  |
| アンダースコア記法  | 単語同士をアンダースコアで連結  | first_name  |

# ◆【番外】　- 変数の参照について -
:::note info
**更新履歴**
・2022/10/3 : **「var」と「let」・「const」のスコープの違い** を追加しました。
:::

番外と記載しているが、この概念を理解しておく事は非常に重要。

## ・ 理解しておくべき用語
| 用語名 | 意味 |
|:-|:-|
|**スコープ**   |「変数がプログラムの中のどこから参照できるのか」を決める概念   |
|**グローバルスコープ**   |プログラム全体からアクセスができる   |
|**グローバル変数**   |プログラム全体からアクセスができる変数   |
|**ローカルスコープ**   |定義された関数の中でのみ参照ができる   |
|**ローカル変数**   |定義された関数の中でのみ参照ができる変数   |
|**関数**|何かしらの入力値を与えることで、あらかじめ決められた処理を行い、その結果を返す仕組み|

### 具体例
```javascript
// グローバル変数
let globalMessage = "GLOBAL";

/**
 * 関数：　callMessage
 * 中でローカル変数を定義し、ローカル変数とグローバル変数の値を出力するという処理を実行する。
 */
function callMessage() {

 // ローカル変数
 let localMessage = "LOCAL";
 
 // ↓ グローバル変数はどこからでもアクセス可能。
 console.log(globalMessage);
 console.log(localMessage);
}


// 出力：　GLOBAL
console.log(globalMessage);

// 出力：　GLOBAL LOCAL
console.log(callMessage);

// ↓ ローカル変数は宣言した関数の中でしかアクセスできないので、エラーになる。
console.log(localMessage);
```



## ・ 変数宣言を省略したらどうなるのか
**結論としては、**
**<font color="red">宣言を省略して定義した変数は全て、グローバル変数として見做される</font>**

```javascript
msg = "Hello";

function sleep() {
  msg = "I'm sleepy";
  console.log(msg);
}

// ③
console.log(msg);     // 出力：　I'm sleepy

// ④
console.log(sleep()); // 出力：　I'm sleepy

```
とある事情により
③の出力では　Hello　を、
④では関数を使用し、　I'm sleepy　を出力したいとする。
しかし関数内で宣言したmsgが、関数の外で宣言したmsgを上書きしてしまっている。

このような事象は予期しないバグの要因等になりかねないので、省略は基本的にはやらないようにすること。

## ・ 「var」と「let」,「const」のスコープの違い
**結論**
| 変数宣言 | スコープ | 説明 |
|:-:|:-:|:-|
|**var**   |<font color="red">関数スコープ</font>|関数単位で参照が変わる|
|**let, const**|<font color="blue">ブロックスコープ</font>|{}（ブロック）単位で参照が変わる|

## ・ 具体例(var で宣言した場合)

```javascript
var a = "GLOBAL";

function num() {
    var a = "LOCAL_1";
    if(true) {
        var a = "LOCAL_2";
        console.log(`if文の中のaは${a}`);
    }
    console.log(`if文の外のaは${a}`);
}

console.log(`関数の外のaは${a}`);

num();

/**
 * 出力結果
 * 関数の外のaはGLOBAL
　　* if文の中のaはLOCAL_2
 * if文の外のaはLOCAL_2
 */
```
上記のように、
<font color="blue">関数num()内の　変数a</font>　の値が、
<font color="green">if文内の　変数a</font>　によって上書きされている。

つまりvarで宣言した変数は、**同じ関数内であれば**　参照も同じになる。

## ・ 具体例(let で宣言した場合)
```javascript
let a = "GLOBAL";

function num() {
    let a = "LOCAL_1";
    if(true) {
        let a = "LOCAL_2";
        console.log(`if文の中のaは${a}`);
    }
    console.log(`if文の外のaは${a}`);
}

console.log(`関数の外のaは${a}`);

num();

/**
 * 出力結果
 * 関数の外のaはGLOBAL
　　* if文の中のaはLOCAL_2
 * if文の外のaはLOCAL_1　★
 */
```
上記のように、
<font color="blue">関数num()内の　変数a</font>　の値と、
<font color="green">if文内の　変数a</font>　の値は異なっている。

つまりletで宣言した変数は、
同じ関数内でも、**{}（ブロック）が違えば**　参照も異なる。

目的に応じて使い分けるのも良いかもしれないが、
意図しないところで参照や値の上書きができてしまうvarではなく、
<font color="red">より範囲が限定的な　**let**　を使用するのが良い。</font>

# 参考文献

https://gihyo.jp/book/2016/978-4-7741-8411-1