Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】JavaScript Core Fundamentals: var, let, const, Scope, and Closures

2025年10月05日に「Dev.to」が公開したITニュース「JavaScript Core Fundamentals: var, let, const, Scope, and Closures」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

JavaScriptの変数宣言var, let, constは、有効範囲(スコープ)や再代入のルールが異なる。varは関数スコープ、let/constはブロックスコープだ。宣言がスコープ先頭に移動するホイスティングや、関数が定義時の環境を記憶するクロージャも重要で、これらを理解し使い分ける必要がある。

ITニュース解説

JavaScriptにおいて、変数の宣言方法と変数の有効範囲を理解することは、堅牢で保守性の高いコードを記述するために不可欠である。本解説では、varletconstという三つの変数宣言キーワードの具体的な違い、変数がアクセス可能な範囲を決定する「スコープ」の概念、そしてJavaScriptの強力な機能である「クロージャ」について、システムエンジニアを目指す初心者にも分かりやすく説明する。

まず、varletconstの最も重要な違いは、その「スコープ」の扱い方にある。varで宣言された変数は「関数スコープ」または「グローバルスコープ」を持つ。これは、関数内で宣言されたvar変数はその関数内でのみ有効であり、どの関数内でもない場所で宣言された場合はプログラム全体で有効となることを意味する。一方、letconstで宣言された変数は「ブロックスコープ」を持つ。ブロックスコープとは、{}(波括弧)で囲まれたコードブロック(例えばif文やforループ、または単なる独立したブロック)内で宣言された変数が、そのブロック内でのみ有効となる性質である。ブロックを抜けるとこれらの変数は参照できなくなるため、変数名の衝突を防ぎ、コードの局所性を高めることに役立つ。

スコープには、主にグローバルスコープ、関数スコープ、ブロックスコープの三種類がある。グローバルスコープは、どの関数やブロックの内側でもない、プログラムの最上位で宣言された変数に適用される。これらの変数はプログラムのどこからでもアクセス可能である。関数スコープは、特定の関数内で宣言された変数に適用され、その関数内でのみ変数にアクセスできる。関数の外からは参照できないため、変数が意図せず他のコードに影響を与えることを防ぐ。ブロックスコープは、letconstで宣言された変数が{}ブロック内で定義された場合に適用され、そのブロック内でのみ変数が有効となる。例えば、関数内でlet myPodcastName = "ExtendWomenInTech";と宣言した場合、myPodcastNameはその関数内でのみ有効であり、関数外で参照しようとするとエラーが発生する。同様に、独立した{}ブロック内でlet topic = "Learning Scope";と宣言すると、topicはそのブロックを抜けた瞬間に参照できなくなる。

変数の「代入」と「再代入」の挙動も、各キーワードで異なる。varletは、宣言後に新しい値を再代入することが可能である。例えば、let message = "Hello outside";と宣言した後、message = "Hello inside";のように値を更新できる。しかし、constは一度値を代入すると、その変数自体に別の値を再代入することはできない。const user = { name: "Alice" };と宣言した場合、user = { name: "Bob" };のように新しいオブジェクトをuserに再代入しようとすると、型エラーが発生する。ただし、constで宣言された変数がオブジェクトや配列のような参照型の値を持っている場合、そのオブジェクトや配列の「中身」(プロパティや要素)は変更(ミューテーション)することが可能である。上記のuserの例では、user.name = "Tsedey";のように、オブジェクトのプロパティの値を変更することは許可される。これは、constが変数の参照先を固定するものであり、参照先のオブジェクトの内容まで不変にするものではないためである。

次に、「ホイスティング」というJavaScriptの特別な動作を理解することが重要である。ホイスティングとは、JavaScriptのコードが実行される前に、varletconstによる変数宣言が、あたかもそのスコープの先頭に「持ち上げられた」かのように処理される現象である。しかし、この持ち上げられた宣言がどのように初期化されるかには違いがある。varで宣言された変数は、ホイスティングされた時点で自動的にundefinedという値で初期化される。そのため、var a = 10;という宣言より前にconsole.log(a);を実行してもエラーにはならず、undefinedが出力される。一方、letconstで宣言された変数は、ホイスティングはされるものの、値は初期化されない。そのため、宣言文に到達する前にこれらの変数を参照しようとすると、「Temporal Dead Zone(TDZ:一時的デッドゾーン)」という状態にあり、ReferenceError(参照エラー)が発生する。これは、undefinedによる予期せぬ挙動を防ぎ、より安全なコードを促すための設計である。

最後に、「クロージャ」という概念は、JavaScriptの強力な機能の一つである。クロージャとは、「関数がその定義された語彙的スコープ(レキシカルスコープ)を記憶し続ける」仕組みを持つ関数のことである。より具体的に言うと、ある関数(内部関数)が別の関数(外部関数)内で定義され、その内部関数が外部関数スコープの変数にアクセスできるとき、外部関数が実行を終えても、返された内部関数はその外部変数を記憶し続けることができる。例えば、outerという関数がcountという変数を持ち、countをインクリメントするinnerという関数を返すと仮定する。このとき、outer関数の実行が完了した後でも、返されたinner関数はcountの値を記憶し続け、innerが呼び出されるたびにcountを更新できる。これは、プライベート変数や状態を保持するようなパターンを実装する上で非常に有用な機能である。

これらのvarletconstの選択、スコープの理解、そしてホイスティングやクロージャといったJavaScriptのコアな概念を深く理解することは、堅牢で保守性の高いプログラムを記述するために不可欠である。現代のJavaScriptでは、デフォルトでconstを使用し、値の再代入が必要な場合にのみletを使用することが推奨される。varは特定のレガシーコードのデバッグを除き、ほとんどの場合避けるべきである。これらの基礎知識を習得することで、システムエンジニアとしてのスキルを大きく向上させることができる。

関連コンテンツ

関連IT用語