JavaScriptの「スコープ」という名の地図:レキシカルスコープの魔法
こんにちは。JavaScriptの世界へようこそ。
コードを書いていると、「あれ、この変数、どこから呼べばいいんだっけ?」と迷子になることはありませんか?実はそれ、あなたが悪いのではなく、JavaScriptが持っている「レキシカルスコープ」というルールを知るだけで、驚くほどスッキリ解決する問題なんです。
今日は、この「どこからどこまでが見えるのか」というルールについて、少しだけ肩の力を抜いてお話ししますね。
—
「レキシカルスコープ」って、つまり何?
専門用語で「レキシカル(Lexical)」と言うと難しく聞こえますが、要は「定義した場所(ソースコード上の位置)」でスコープが決まる、という意味です。
これを身近な例えで考えてみましょう。「マイホームのルール」を想像してください。
- レキシカルスコープの考え方:
あなたがどの家で育ったか(どこで定義されたか)によって、その家の冷蔵庫の中身(変数)を使えるかどうかが決まります。たとえあなたが引っ越し(関数を別の場所で呼び出し)をしても、あなたの「実家のルール(変数の参照先)」は変わりません。
「どこで実行されたか」ではなく、「どこで生まれたか」が全て。これがレキシカルスコープの鉄則です。
—
動的スコープとの違い:ちょっとした混乱の種
もしJavaScriptが「動的スコープ」だったらどうなっていたでしょう?
これは、「今、その関数を呼び出している場所」によって使える変数がコロコロ変わるというもの。
例えるなら、「遊びに行った先の友達の家の冷蔵庫を、勝手に自分の冷蔵庫だと思って開ける」ような状態です。これだと、バグがどこで起きているのか予測不能で、頭がパンクしてしまいますよね。
JavaScriptがレキシカルスコープを採用しているおかげで、私たちはコードを読むだけで「この変数はここにあるはず!」と、パズルのピースを当てるように正確に状況を把握できるんです。
—
実際にコードで見てみましょう
百聞は一見に如かず。簡単なコードで、「どこで生まれたか」がどれほど重要か見てみましょう。
// グローバル(世界共通の冷蔵庫)
const snack = “ポテトチップス”;
function myRoom() {
// 自分の部屋(myRoom関数)の中で定義されたもの
const snack = “チョコレート”;
function eat() {
// 自分の部屋の冷蔵庫(snack)を見に行く
console.log(“食べているのは:” + snack);
}
return eat;
}
const myEat = myRoom();
myEat(); // 「食べているのは:チョコレート」と表示されます
この例では、`eat` 関数は `myRoom` という「部屋」の中で生まれました。だから、外の世界(グローバル)に「ポテトチップス」があっても、まずは自分の部屋の「チョコレート」を優先して見つけに行きます。
これがレキシカルスコープの「内側から外側へ向かって探す」という性質です。
—
つまずきやすいポイント:大丈夫、怖くないですよ!
初心者の頃、一番混乱するのは「関数を呼び出す場所」を意識しすぎてしまうことかもしれません。
「この関数、あっちの場所から呼んだら、あっちの変数が見えるんじゃないの?」
そう思ってしまうのは、自然なことです。でも、もう一度だけ思い出してください。「定義された場所」が全てです。関数がどこで呼び出されようが、関数は自分が生まれたときの「実家(定義場所)」の情報をずっと覚えています。
もし変数がうまく見つからなければ、コードを上から眺めて、その関数が「どの波括弧 `{ }` の中に囲まれているか」を見てみてください。それが、その関数の「実家」です。
—
まとめ:コードの地図を読み解こう
- レキシカルスコープ=「定義された場所」で決まるルール。
- 関数は生まれた場所のスコープを一生忘れない。
- 探すときは、自分の部屋(内側)から外側の部屋(外側)へ順番に探す。
JavaScriptは、一見気まぐれに見えて、実はとても誠実で論理的な言語です。「どこで定義したっけ?」と迷ったときは、コードの波括弧を指でなぞりながら、その関数の「実家」を探してみてください。
最初から完璧に理解できなくても大丈夫。少しずつ、このスコープという「地図」が頭の中に描けるようになると、コーディングはもっともっと楽しくなりますよ。
それでは、また次回の冒険でお会いしましょう!応援しています。

コメント