【JavaScript】varとletの違いを調べてみた
過去に以下のような記事を書きました。
大変ありがたいことに以下のようなコメントをいただきました。ありがとうございますm( _ _ )m
なぜvarを使うとバグの温床になるのかという点を書いてもらうと、もっと良い記事になりそうです。
説明できないと思い、コード書いて試してみましたので記事にします。
varとletの違い
表形式で両者の違いをまとめてみます。
var | let | |
---|---|---|
再代入 | できる | できる |
再宣言 | できる | できない |
スコープ | 関数スコープ | ブロックスコープ |
ここでスコープについて補足です。
関数スコープとは、関数ごとに作られるスコープのこと
const func = () => { // === ここから関数スコープ === var str = "umumum"; console.log(str); ...(その他処理) // === ここまで関数スコープ === }
ブロックスコープとは、ブロック{ }
ごとに作られるスコープのこと
それでは まず、varを使って変数定義したサンプルコードから確認します。
const output = () => { var num = 10; console.log(num); // 10 { var num = 99999999; // 再宣言 console.log(num); // 99999999 var str = "ガムかむ" } console.log(num); // 99999999 console.log(str); // ガムかむ };
output(); // 10 (1行目) // 99999999 (2行目) // 99999999 (3行目) // ガムかむ (4行目)
関数outputを実行した結果の3行目に注目します。
varで宣言した変数num
では、再宣言が可能なのでvar num = 99999999;
で変数num
に格納された値が99999999となりました。
4行目にも注目します。
varで宣言した変数str
は、関数outputで作られた関数スコープで使用できます。
そのためconsole.log(str);
での出力が可能になっています。
次に、letを使って変数定義したサンプルコードを確認します。
const output = () => { let num = 10; console.log(num); // 10 { let num = 99999999; console.log(num); // 99999999 let str = "ガムかむ" } console.log(num); // 10 console.log(str); // not defined };
output(); // 10 (1行目) // 99999999 (2行目) // 10 (3行目) // Uncaught ReferenceError: str is not defined (4行目)
関数outputを実行した結果の3行目に注目します。
let num = 99999999;
はブロック内で使用できる変数num
を定義しているだけです。
let
では再宣言はできないですし、ブロックスコープなのでnum
の値が10 -> 99999999
にはなりません。
同じく4行目にも注目します。
str
が定義されていないというエラーになります。
原因は単純です。let str = "ガムかむ"
で宣言している変数str
は
ブロックスコープ外のconsole.log(str);
では参照できない変数だからです。
なぜvarは推奨されないのか
両者の違いを上記で確認したところで、本記事の本題です。 varが推奨されない理由としては、次のことが挙げられると思います。
- 再宣言が可能であるために、予期せぬ変数値の書き換えが発生しやすくなる
関数スコープが広いと、気付かずに同じ変数名を使用して
別の目的で変数宣言してしまうこともあり得ると思います。
そんなシーンでは予期しない書き換えが起こることがイメージできます。
let
を使用すれば再宣言するとコンソールにエラーが吐かれるので気づくことができますね。
結論
というわけで