JavaScript | 基礎構文:変数・定数 – ブロックスコープ

JavaScript
スポンサーリンク

まず「ブロックスコープ」を一言でいうと

ブロックスコープは、
{ ... } のカタマリの中だけで有効な“変数の生息範囲”」 のことです。

JavaScript の letconst で宣言した変数は、
この「ブロック(= {} の中)」を単位にして、

その中だけ見える
外からは見えない

という「見える/見えないの境界」が決まります。

ここが重要です。
「どこからどこまで、その変数が見えるか(使えるか)」を決めるルールがスコープ。
その中でも {} を単位とするものが「ブロックスコープ」。
let / const はこのルールに従う。


ブロックとは何か:ただの「{ } のかたまり」

if や for の「かっこ」がブロック

次のコードを見てください。

if (true) {
  const message = "こんにちは";
  console.log(message); // ここでは使える
}

console.log(message); // エラー:message はここでは定義されていない
JavaScript

{ ... } で囲まれた部分(if の中)が「ブロック」です。

この中で宣言された message は、
このブロックの外からは見えません

同じように、forwhile もブロックを作ります。

for (let i = 0; i < 3; i++) {
  const text = "ループ中";
  console.log(i, text); // ここでは i も text も見える
}

console.log(i);    // エラー:i はここでは定義されていない
console.log(text); // エラー
JavaScript

ループの {} の中が「ブロック」であり、
その中で宣言された変数はブロックスコープに従って、
ブロックの外には漏れません。

ブロックは単なる「任意の { } 」でもよい

iffor がなくても、
単に {} で囲んだだけでブロックを作れます。

{
  const x = 10;
  console.log(x); // 10
}

console.log(x);   // エラー:x はスコープ外
JavaScript

この { ... } の中が一つの「ミニ世界」になっていて、
そこで宣言された x は「そのミニ世界専用」の変数です。

ここが重要です。
ブロック = {} で囲まれた範囲。
let / const で宣言した変数は、そのブロックの中だけで有効になる。
ブロックの外からは見えないし、触れない。


let / const と var の違い:ブロックスコープがあるかどうか

let / const はブロックスコープ

例をもう一度整理します。

if (true) {
  let a = 1;
  const b = 2;
  console.log(a, b); // 1, 2
}

console.log(a); // エラー
console.log(b); // エラー
JavaScript

ab も、if の中(ブロックの中)でしか使えない変数です。

これは直感に合います。

「この if の条件が true のときだけ使う一時的な変数」
「この for の中だけで使うカウンター」

そういうものはブロックの中に閉じてくれたほうが安心ですよね。

var はブロックを無視する(関数スコープ)

var はブロックスコープを持たない、というのがややこしいところです。

if (true) {
  var x = 10;
  console.log("中:", x); // 10
}

console.log("外:", x);   // 10(えっ…? 見えてしまう)
JavaScript

if の中で宣言したつもりの x が、
if の外でも見えてしまいます。

ループでも同じです。

for (var i = 0; i < 3; i++) {
  console.log("ループ内:", i);
}

console.log("ループ外:", i); // 3(i が漏れている)
JavaScript

var は「関数スコープ」で、
「関数の中かどうか」は見るけれど、「ブロックの中かどうか」は見ない
というルールになっています。

ここが重要です。
let / const は「ブロックごとに変数の世界を分ける」。
var はそれをしないので、意図せず変数が外に漏れてバグの元になる。
だから、今は let / const を使おう、という話につながります。


ブロックスコープが役に立つ場面

その場限りの変数を外に漏らさない

例えば、次のような処理を考えます。

if (user.isAdmin) {
  const message = "管理者としてログインしました";
  console.log(message);
}

// ここでは message はもう不要
JavaScript

message は、「管理者チェックの場面」でだけ使いたいものです。
if の外で使う必要はありません。

ブロックスコープのおかげで、
message は if の外からアクセスできないので、
「間違って他の場所で使ってしまう」リスクをなくせます。

同じ名前を「別のブロック」で再利用できる

次のコードを見てください。

{
  const value = 1;
  console.log("ブロック1:", value); // 1
}

{
  const value = 2;
  console.log("ブロック2:", value); // 2
}
JavaScript

両方とも value という名前ですが、
別々のブロックなので、別々の変数として扱われます。

これは、関数内の for でもよく使います。

for (let i = 0; i < 3; i++) {
  console.log("ループ1:", i);
}

for (let i = 0; i < 2; i++) {
  console.log("ループ2:", i);
}
JavaScript

どちらも i ですが、
各ループの {} の中だけに存在する i なので、
互いに干渉しません。

ここが重要です。
ブロックスコープがあることで、「その場限りの変数」を外に漏らさずに済む。
結果として、同じ名前も「別のブロックごとに安心して再利用」できる。


ブロックスコープを意識すると、バグが減る理由

「この変数、どこから使われている?」が分かりやすくなる

例えば、ファイルの上のほうにこう書いてあったとします。

let temp = 0;
JavaScript

その後、長いコードの中で 10 回以上 temp が出てくると、
「どこで使っていて、どこで書き換えているのか」を追うのが大変になります。

一方、ブロックスコープをきちんと使うと、
一時的な変数はなるべくブロックの中に閉じ込めてしまいます。

function process() {
  {
    let temp = calcSomething();
    console.log(temp);
  }

  {
    let temp = calcAnotherThing();
    console.log(temp);
  }
}
JavaScript

temp はどちらも「そのブロックの中で完結している変数」なので、
「他の場所から触られない」「紛れ込んだバグも局所的で済む」
というメリットがあります。

「変数の寿命」を短くする発想

ブロックスコープを上手く使う人は、
「変数の寿命をできるだけ短くしよう」と意識しています。

寿命が短い=使う範囲が狭い

使う範囲が狭い=

  • 追いかけるべきコードの量が減る
  • どこで壊れたかを見つけやすい

ということです。

ここが重要です。
**ブロックスコープを意識して「変数を狭い範囲に閉じ込める」と、

  • 変数名の衝突が減る
  • どこでどう値が変わるか把握しやすい
    結果として、バグの温床を減らせる。**

まとめ:ブロックスコープをどう捉えればいいか

最後に、初心者向けにシンプルにまとめます。

ブロックスコープとは、「{} の中だけ有効な変数の有効範囲」のこと。

let / const で宣言した変数は、その {} の中だけで見える。
外からは見えない。

if の中、for の中、任意の {} など、それぞれが「ミニ世界」。
その中で作った変数は、そのミニ世界だけで使う。

var はブロックスコープがなく、ブロックの外にも変数が漏れるので、予期せぬ上書きやバグの原因になりやすい。
だから今は let / const を使うのが普通。

ブロックスコープを意識して、
「その場限りの変数は、その場(ブロック)の中に閉じ込める」ようにすると、
コードが読みやすく、安全になる。

ここが重要です。
ブロックスコープを一言で言えば、「変数の“見える範囲”を、{} ごとに小さく区切るルール」。
これを味方につけると、「変数が勝手にどこかで書き換わっていた…」という、初学者がハマりがちな泥沼をかなり避けられます。

もしよければ、小さなファイルを作って、

if (true) {
  let a = 1;
}
console.log(a); // どうなる?
JavaScript

や、

for (let i = 0; i < 3; i++) {
  const msg = "中";
}
console.log(i, msg); // どうなる?
JavaScript

のようなコードを実際に動かしてみてください。

「ここでは見える」「ここでは見えない」を自分の目で確認すると、
ブロックスコープの感覚が一気に身体に入ってきます。

タイトルとURLをコピーしました