変数の宣言、再代入、スコープ

※プログラミング学習中の私がアップロードしてます。理解が浅いです。
この記事は厳密な仕様に関するものではなく、考え方理解のまとめとして受け取ってください。

var
-

letとconstの性質を説明する前に、「var」という変数について

以前までは変数宣言にvarのみを使用していましたが、ES6の環境から「let」と「const」が新たに追加されました。
varはスコープの範囲を広げる自由度の高い変数のため、意図していないエラーが起こり得ることから、使用頻度は低めです。＊＊特別な意図がない限りはletとconstを使うように。＊＊

let, const, varには、以下のような特徴があります。

|変数|let|const|var|
|:--:|:--:|:--:|:--:|
|再代入|○|☓|○|
|再宣言|☓|☓|○|
|ブロックスコープ|○|○|☓
|関数スコープ|○|○|○


letとconstの使いかた
-

|変数の宣言方法|
|--|
letとconstの宣言方法に違いはなく、文字列や数字、配列などを格納することができます。

```javascript
//let
let number = 1;
let string = 'letの場合';
let array = [a, b, c];
let object = {id: 1, name: 'yamada'};

console.log(number); //1
console.log(string); //letの場合
console.log(array[2]); //c
console.log(object.name); //yamada

//const
const number = 50;
const string = 'constの場合';
const array = [x, y, z];
const object = {color: 'yellow', price: 500};

console.log(number); //50
console.log(string); //constの場合
console.log(array[0]); //x
console.log(object.price); //500
```

値の参照が必要な場合や、他の関数に再利用するときなどに使われます。

|再代入|
|--|

一度宣言した変数を更新することを再代入といいます。
letは値の再代入ができる一方で、constはできません。

letの場合
-

```javascript
let a = 1; //変数宣言
a = 10; //再代入
console.log(a); //10
```

constの場合
-

```janet
const b = 1; //変数宣言
b = 10; //再代入
console.log(b); // Assignment to constant variable.
```

変数を再代入するケースはあまり多くありませんが、ループ処理などの変数の数値が変わるような場合などに、letを用いて再代入をすることがあります。例えば、ボタンをクリックするごとに、回数をカウントし、カウント数値を保持する必要がある場合などに、letが役に立ちます。

|再宣言|
|--|

一度宣言した変数を、同じ変数名を使って再び宣言をし直すことを再宣言と言います。
letとconstどちらも2回以上宣言することはできません。

letの場合
-

```javascript
let a = 1; //変数宣言
let a = 10; //再宣言
console.log(a); // SyntaxError: Identifier 'a' has already been declared
```

constの場合
-

```javascript
const b = 1; //変数宣言
const b = 10; //再宣言
console.log(b); // SyntaxError: Identifier 'b' has already been declared
```

プログラムが長くなってくると、誤って同じ変数名をつけてしまうことがあるかもしれません。再宣言ができないメリットとして、このように別用途の変数に同じ変数名をつけてしまうことを防ぐことができます。

|スコープについて|
|--|

ここからは変数とスコープの関係性について説明していきます。

スコープとは？
-

「スコープ」とは、変数や関数の有効範囲のことです。通常、ある変数の有効範囲外からアクセスしようとしても、その変数にアクセスすることができません。スコープを意識することで、予期せぬ不具合を防ぎ、より安全なプログラムを書くことができます。

スコープには「グローバルスコープ」と「ローカルスコープ」の2種類が存在します。

グローバルスコープ
-
プログラムのどこからでもアクセスできる範囲のことをグローバルスコープと言います。プログラムの一番外側すなわちトップで宣言されたlet, const, varいずれかの変数は、グローバスコープを持ち、グローバルスコープを持つ変数のことをグローバル変数と言います。

```javascript
let a = 1;

console.log(a); //1
function global() { 
 　console.log(a); // 1
}
global(); 
```

トップ直下からのアクセスや関数内からのアクセスができるように、一番外側で宣言した変数aは、グローバルスコープを持ち、あらゆる場所からアクセスを許します。

ローカルスコープ
-

プログラムの特定の範囲内でアクセスを許可する変数のことをローカル変数と呼び、その変数が持つ有効範囲のことをローカルスコープと呼びます。
ローカルスコープは、「ブロックスコープ」と「関数スコープ」の2種類に分類されています。

ブロックスコープ
-

ブロックスコープとは、ブロック{}ごとに囲まれた範囲のことです。
ブロック内でletやconstで宣言された変数は、ブロックスコープを作り、ブロックスコープ外からのアクセスを制限します。

一方、varで宣言された変数は、ブロックスコープを持つことはできません。そのため、外からのアクセスを許可します。

```javascript
{
　let a = 1;
　const b = 10;
　var c = 100;
}

console.log(a); //ReferenceError: a is not defined
console.log(b); //ReferenceError: b is not defined
console.log(c); //100
```

letとconstはブロックスコープを作るためエラーが返ってきますが、varの場合は、ブロックスコープを作ることができないため、値を参照することができます。
varで宣言された変数は、自由度が高く一見便利そうにも思えますが、どこからでもアクセスすることができ、意図せずに値を変更してしまう恐れがあるため、注意が必要です。

関数スコープ
-

関数スコープとは、関数のブロック{}ごとに作られる範囲のことです。
関数スコープ内でlet、const、varのいずれかで宣言された変数は、関数スコープの外からはアクセスできません。

```javascript
function scope() {
　let a = 1;
　const b = 10;
　var c = 100;


　a = 2; //再代入 

　console.log(a); //2
　console.log(b); //10
　console.log(c); //100
}
scope();

console.log(a); //ReferenceError: a is not defined
console.log(b); //ReferenceError: b is not defined
console.log(c); //ReferenceError: c is not defined
```

関数のブロック内で変数にアクセスしたものは、それぞれ値を参照することができますが、関数のブロック外からはアクセスできないため、エラーとなり、値を参照できないことがわかります。

>TDC:WorPress
>https://tcd-theme.com/2021/04/javascript-let-const.html?gclid=CjwKCAjwv_iEBhASEiwARoemvFcKnW6za6trJPlW_I6uEh1JpSOmiC1qj4dLjCQf4hUofDbpCOwyJBoCldwQAvD_BwE