JavaScriptの変数宣言について
はじめまして。見習いエンジニアです。学んだことのアウトプットとしてたまに記事を投稿したいと思います。
JavaScriptには変数宣言で利用できるキーワードが3つあります。
var
とlet
とconst
の3つです。この違いを見ていきましょう。
var let constの違い
再宣言 | 再代入 | スコープ | ホイスティング | |
---|---|---|---|---|
var | ○ | ○ | 関数 | undefined |
let | × | ○ | ブロック | エラー |
const | × | × | ブロック | エラー |
再宣言とは
その名の通り、同じ変数名を再度宣言してしまうことです。
var
は再宣言してしまうと、最初に宣言した変数を上書きしてしまいます。
let
とconst
は再宣言不可であり、間違えて再宣言してしまった場合もエラーで知らせてくれます。
var myVar = 0;
var myVar = 10;
console.log(myVar); // 10
const myConst = 0;
const myConst = 10; // SyntaxError: Identifier 'myConst' has already been declared
再代入とは
再代入とは、既に宣言された変数に新しい値を割り当てることです。
var
とlet
は再代入可能ですが、const
はできません。
var myVar = 0;
myVar = 10;
console.log(myVar); // 10
let myLet = 0;
myLet = 10;
console.log(myLet) // 10
const myConst = 0;
myConst = 10; // TypeError: Assignment to constant variable.
しかしながら、const
で宣言した配列やオブジェクトは変更可能です。
数値や文字列はイミュータブルなため変更できませんが、配列やオブジェクトはミュータブルなため変更が可能です。
const products = {
name: "apple"
};
products.name = "orange";
console.log(products.name) // "orange"
const number = [1, 2, 3];
number[0] = 0;
console.log(number) // [0, 2, 3]
スコープとは
スコープとは、変数や関数が有効でアクセス可能な範囲を指します。
JavaScriptでは
- グローバルスコープ(プログラム全体からアクセス可能)
- 関数スコープ(関数内でのみアクセス可能)
- ブロックスコープ(if文やfor文などのブロック内でのみアクセス可能)
の3種類があります。
var
は関数スコープであり、予期せぬ再宣言を行ってしまう可能性があります。
ホイスティングとは
巻き上げとも呼ばれ、変数や関数の宣言が、実際のコード実行前にそのスコープの最上部に「持ち上げられる」動作を指します。
var
で宣言された変数は関数スコープまたはグローバルスコープの先頭にホイスティングされます。ただし、初期化はそのままの位置に留まります。
これがどういう現象を実際に引き起こす可能性があるのかと言うと、var
はundefined
で処理するためエラーが発生せず、意図しない挙動やバグが発生してしまいます。
一方、let
やconst
ではその時点でエラーを出してくれるので、原因の特定が簡単になります。
console.log(hoge); // undefined
var hoge = 5;
console.log(hoge); // 5
このコードは以下のように解釈されます。
var hoge;
console.log(hoge); // undefined
hoge = 5;
console.log(hoge); // 5
let
とconst
で宣言された変数も正確にはホイスティングされますが、宣言が初期化されるまで一時的にテンポラルデッドゾーンに留まるため、
宣言前にアクセスするとエラーが発生します。
おわり
以上がvar
とlet
とconst
の違いです。
私は以前研修を受けたときにとりあえずvar
使っておけと言われたのですが、学びなおしてみると現実は異なっておりました。
2023年に研修を受けたはずなのですがきっと2015年以前にタイムスリップしてたのでしょう。