NACの勉強の経過を綴るところ

個人的なコードの勉強

【JS】letとvarとconstの使い分け

JS逆引きレシピ本、007,008(P18、19)。


いままで、変数を定義する場合には、ほぼvarを使用してきた。
letの存在は知ってはいたものの、使い分けの意味を理解できず、困ってもいなかったのでletを使ったことは、ほぼないに等しい。


本によると、letとvarでは、letを使うべき、とある。

JavaScriptではもう1つ、変数を宣言するためにvarという命令を利用できます。構文はletと同じですが、挙動が異なります。

  • 同名の変数を許容(letではエラー)
  • ブロックスコープを認識できない

1項目は、なるほど、と思った。
iやjなどの、やたらと使うどうでもいい変数はvarでいいとして、それ以外はletの方がバグの発生を未然に防げそうである。


2項目、「ブロックスコープ」?
知らない単語出てきた。


調べると、変数の有効範囲(スコープ)が「宣言したブロック内でのみ有効」であることを指すらしい。
概念は理解していたもので、それを「ブロックスコープ」と呼ぶことを知らなかった。
こういうのも、学習機会を設けずに泥縄で覚えてきた弊害である。


で、letの方はブロックスコープであるのに対し、varで宣言した変数はブロックスコープではない、と。
本の方での説明に戻ると、

if (true) {
    let x = 10;
}

consol.log(x); // エラー「x is not defined」
if (true) {
    var x = 10;
}

consol.log(x); // 10

if ( ) {~} はブロックなので、letで宣言した変数は外部に持ち出せないのに対し、varはブロックスコープではないので、ブロック外でも参照できる。


ただ、続く文章がよくわからない。

スコープはできるだけ限定するという観点からも、varよりもletを利用すべきなのです。

そうなの?
単に、スコープ範囲が違うので使い分けようね、というだけで、「スコープはできるだけ限定する」のが何のためだかよく分からない。
変数がスコープ外に無分別に流出すると、スクリプトが汚染されて煩雑になる、という観点だろうか。


なんとなくではあるが、使い分ければいいだけな気がするし、ブロック内外で共通して変数を活用したい局面は多いような気がする。
むしろ、varを基本としつつ、ブロック内だけで完結させたい場合に限ってletを使えばいいのでは、という気がしてしまう。
これは、JSの経験値が少ないゆえの発想なのだろうか……。

constについて

ちなみに、constは変数ではなく定数。
一度値を格納したら再代入できない。
PHPでいうところのdefine()である。


理解はしていたし、使うことがないわけではないが、なんとなく変数を使ってしまう機会が多かった。
自分が間違えなければいいだけで、varで宣言した変数であっても、定数のごとく「二度と再代入しないように」気をつけていればいいだけなのでは、と思っていたから。


それが、本には以下のような説明が。

再代入されない変数をletで宣言することは、「(変化しないにもかかわらず)どこかで値が変わるかもしれない」可能性を意識しながらコードを読まなければならないという意味で、可読性を落とします。

なるほど~。


その視点はなかった。
ちょっと目からウロコ。
次から気をつけてみようと思う。