【JavaScript】var,let,constの使い分け(constは定数ではない)

初心者がJavaScriptを学ぶ上で最初に混乱するvar,let,constに関して、
どうやって使い分けていけば良いか解説する。

結論

最初に結論から言うと、以下のように覚えておけば大丈夫。

  • 基本はconst一択
  • どうしても変数の再代入をしなければ表現できないときはlet
  • varを使うのは論外

違いを説明

まずはそれぞれの特性を説明する。

const

const再代入不可な変数を宣言するためのものである。
Javaでいうところのfinal

constによって宣言された変数に、もう一度何かを代入しようとした場合、エラーになる。

// 宣言
const hoge = 10;

// 再代入しようとすると、エラー
hoge = 5;

後述するが、constは「定数」だと考えると納得がいかないところが多いと思う。
だから定数ではなく「中身を入れ替えることができない変数」と考えると良い。

let

letは再代入可能(中身を入れ替えることができる)な変数である。
constでエラーになった以下のようなコードはletではエラーにならない。

// 宣言
let hoge = 10;

// 代入できる
hoge = 5;

console.log(hoge);  // 「5」と表示される

var

これはconstletが作られる前から存在した古い宣言方法で、
挙動としてはletに近いが、以下の3つの点がletとは異なる。

  1. 再宣言ができてしまう
  2. ブロックスコープが適用されない
  3. 変数の巻き上げが起こる

詳しい説明は他の記事に任せるが、簡単に説明すると

  • let:他のプログラミング言語の変数仕様に近い
  • var:他のプログラミング言語よりも変数の自由度が高すぎる、特殊な挙動をする

という違いがある。

この特殊な挙動をするというところがポイントで、
ここを完全に理解していないとバグがあるコードを書いてしまう可能性が十分にある。

また、この特殊な挙動は機能としても別にあって便利なものではない。

こういった理由でvarよりもletを使うことが推奨される。

constは「定数」ではなく「再代入不可能な変数」

const=定数」と覚えている人にとっては、
「基本的にconstのみを利用しましょう」と言われると、
「定数のみでプログラムが書けるわけがない」と気持ち悪く感じるだろう。

これに対する回答は「const定数ではなく再代入不可能な変数だから」と考えてほしい。
例を以下に示すが、プログラミングでは再代入不可能な変数を使う方が良いコードになる。

良いコードとは

基本的に良いコードというのは変数の再代入をできるだけ行わない。
なぜなら、その変数に今何が代入されているのか追いやすいからだ。

プログラムの保守を行う際に、コードを読むコストが圧倒的に異なる。

  • letで宣言された変数:使う前に「もしかしたらどこかで変更されているかもしれない」と探す必要がある
  • constで宣言された変数:最初に宣言された値が絶対に入っているので、「他で書き換えられているかも」という心配がない

また、ある変数に違う値を代入する時は大抵意味が変わっていることが多い
意味が異なるものを同じ名前で管理してしまうのは、混乱を招きやすいため
できるだけ再代入不可能な変数を使ってコードを書く方が良い。

悪い例

let price = 100; // 最初の税抜き価格が100円

price = calcTax(price); // 消費税を計算する

console.log(price);  // 税込み価格を表示する

コードを書いた人は「どちらも同じ価格だから」と考えて
priceという変数を書き換えて税込み価格を計算しているが、
税込み価格と税抜き価格というように、代入の前後で意味が変わっている。

上記はコードが短いため確認が簡単だが、
間に長いコードがあった場合は「console.log(price);」だけを見た時に
「このpriceって税込みだっけ?税抜きだっけ?」というふうに
長いコードの中で書き換えられていないか確認しなければいけない。

良い例

const nonTaxedPrice = 100; // 税抜き価格

const taxedPrice = calcTax(nonTaxedPrice); // 消費税を計算

console.log(taxedPrice); // 税込み価格を表示する

これなら「どこかで書き換えられているかもしれない」という確認は不要になるし、
間違ったコードを書いてしまった場合もレビューで気づきやすい。

// 価格を表示する関数を使って税込み価格を表示する
displayPrice(nonTaxedPrice); // ←引数に入れる変数が間違っている!

まとめ

  • 基本はconst一択
  • どうしても変数の再代入をしなければ表現できないときはlet
  • constは定数ではなく再代入不可能な変数
  • 変数の代入はできるだけ行わない方が読みやすいコードになる
タイトルとURLをコピーしました