【入門編】 変数シャドーイング(Variable Shadowing) – JavaScript実践ガイド

こんにちは!フロントエンドの現場で長年コードを書き続けていると、たまに「あれ、さっき決めたはずの値がどこかに消えた?」なんて怪奇現象に遭遇することがあります。

初心者の頃、僕もまさにそれで数時間溶かした経験があります。その犯人の一人が、今日お話しする「変数シャドーイング(Variable Shadowing)」です。

名前はちょっと難しそうですが、仕組みはとてもシンプル。一緒に紐解いていきましょう。

—

変数シャドーイングって、一体なに?

「シャドーイング」という言葉は「影」を意味しますよね。JavaScriptの世界でも、「外側にある変数の上に、内側の変数が影のように覆いかぶさって隠してしまう現象」のことを指します。

身近な例で例えるなら、「手元のメモ」を想像してください。

1. あなたは、リビング(広い場所=グローバルスコープ)に「今日の買い物リスト」を置いています。
2. その横で、あなたが「付箋(小さな場所=ブロックスコープ)」に別のメモを書きます。
3. もしその付箋に「買い物リスト」とタイトルを書いて、元のリストの上にペタッと貼ってしまったら……?
4. あなたは今、どちらのリストを見ますか? もちろん、上から貼った付箋のリストですよね。

これがシャドーイングです。外側の広い場所に名前があるのに、内側の狭い場所で同じ名前をつけてしまうと、外側の存在が見えなくなってしまうんです。

—

コードで見てみよう

百聞は一見に如かず。実際にコードを書いて確認してみましょう。

// 外側の世界(グローバルスコープ)
let message = “お腹すいたな”;

if (true) {
// 内側の世界(ブロックスコープ)
// ここで同じ名前の変数を使っちゃうと…?
let message = “もうお腹いっぱい!”;

console.log(message); // ここでは「もうお腹いっぱい!」が表示される
}

// 最後に外側の世界を見てみると…
console.log(message); // ここでは「お腹すいたな」に戻る

なにが起きたのか?

`if` の中に入った瞬間、JavaScriptくんは「おっ、`message`っていう名前の箱が新しく作られたぞ! 今はこっちを優先しよう」と判断します。これがシャドーイングです。

外側の `message` は消えたわけではありません。ただ、内側にいる間だけ、影に隠れて見えなくなっているだけなんです。

—

なぜこれが「注意点」になるの?

「見えなくなるだけなら別にいいじゃない」と思いますよね? でも、これが大規模なプロジェクトになると、とんでもないバグの温床になります。

  • 勘違いの発生: 「あれ、さっきセットした値が反映されてない!」と必死に探したら、実は内側のスコープで同じ名前の変数を再定義していた……なんてことは、ベテランでもたまにやります。
  • コードの可読性低下: 変数名が被っていると、後からコードを読んだ人が「どっちの変数を指しているんだ?」と混乱してしまいます。

—

現場のアーキテクトからの「知恵」

僕が現場で新人さんに必ず伝えているのは、「あえて同じ名前を使わない」というシンプルなルールです。

もし内側で少し違う意味の値を使いたいなら、`message` ではなく `messageInBlock` や `currentMessage` といった、少しだけ具体的な名前をつけてあげてください。

どうしても同じ名前を使いたい時は?

もし本当にスコープを分けて管理したいなら、`let`や`const`でブロックをしっかり区切ることは素晴らしい習慣です。でも、迷ったら「名前を変える」のが一番の安全策です。

「変数の名前は、その変数が何者かを表す看板」です。看板が二つ重なってどちらか読めなくなったら、トラブルの元ですよね。

—

まとめ:怖がらなくて大丈夫!

変数シャドーイングは、JavaScriptが「スコープ(範囲)」をとても大事にしているからこそ起こる現象です。

  • 内側で宣言された変数は、外側の同じ名前の変数を隠してしまう。
  • でも、外側の変数が消滅したわけではない。
  • 混乱を防ぐために、なるべく名前は被らせないのがベター。

「あ、今の状態はシャドーイングだ!」と気づけるようになったら、あなたはもう立派なJavaScript使いです。

最初は誰だって迷います。もしコードが思い通りに動かなくて「値がおかしいぞ?」と思ったら、この「影の存在」を思い出してみてくださいね。応援しています!

コメント

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