まず「宣言」と「代入」を一言で分ける
先にイメージだけハッキリさせます。
宣言:
「この名前の変数(箱)を使いますよ、とプログラムに伝えること」
代入:
「その変数(箱)の中に、実際の値を入れること」
たとえば、
let x; // 宣言
x = 10; // 代入
JavaScriptこの 2 行は、まったく別の意味を持っています。
ここが重要です。
宣言は「箱を用意する行為」、代入は「箱の中身を決める行為」。
この2つを頭の中でちゃんと分けて考えられるようになると、「未定義」「再代入」など他の概念も一気にスッキリします。
宣言とは何か:変数という「箱」の登録
宣言だけのコードを見てみる
宣言は、変数名をプログラムに「登録」する行為です。
let score;
const name;
JavaScript実際には、const name; はエラーになるので、
宣言だけできるのは let(と var)だけです。
宣言だけした状態を日本語で言うと、
「score という名前の箱を用意した。ただし、中身はまだ決めていない」
という状態です。
宣言だけの変数の中身はどうなっているか
let score;
console.log(score);
JavaScriptこのとき、出てくるのは undefined です。
これは、
- 変数
scoreは「存在する」 - しかし「まだ意味のある値は入っていない」
という状態を表しています。
つまり、
- 宣言:変数が「存在する」ようになる
- でも宣言だけでは、中身の値は「未定義(undefined)」のまま
ということです。
ここが重要です。
宣言した瞬間、“この名前の箱はここにある” という状態にはなるが、
“箱の中身が何か” はまだ決まっていない。
これが「宣言だけ」の状態。
代入とは何か:変数の中身を決める(または上書きする)
最初の代入(初期化)
宣言した変数に、最初に値を入れることが「代入」です。
let score; // 宣言(中身は undefined)
score = 80; // 代入(初期化)
console.log(score); // 80
JavaScriptこの「最初の代入」は、よく「初期化」とも呼ばれます。
宣言と代入を同時に書くこともできます。
let score = 80; // 宣言+代入(初期化)を一度にやっている
JavaScript頭の中では、
let score; // 宣言
score = 80; // 代入(初期化)
JavaScriptの二段階が同時に起きていると思ってください。
2回目以降の代入(再代入)
一度代入したあと、別の値を入れ直すこともできます。
let score = 80; // 宣言+代入(初期化)
score = 90; // 再代入(上書き)
score = score + 10; // 再代入(100になる)
console.log(score); // 100
JavaScript宣言は一回きりですが、
代入は何度でも行えます(const を除く)。
宣言:変数の「存在」を決める
代入:変数の「中身」を決める(または変える)
この役割分担を意識してください。
宣言と代入を混同すると、どうバグるか
宣言を忘れて「代入だけ」してしまうパターン
よくある間違いがこれです。
function doSomething() {
count = 1; // let / const を書き忘れている → 宣言していないのに代入
}
JavaScript本当はこう書くべきです。
function doSomething() {
let count = 1; // 宣言+代入
}
JavaScript宣言を書き忘れると、非 strict mode では
- JavaScript「
countという名前は知らないな…。じゃあグローバル変数として作っちゃえ」
となり、暗黙的なグローバル変数が勝手に増えます。
これがいわゆる「暗黙的なグローバル」で、
別の場所の変数と名前がかぶったりして、非常にバグの元になります。
宣言と代入をしっかり区別しないと、
「宣言したつもりで、実はしてない」という危険な状態を生み出しやすくなります。
宣言と代入を同時にしか書かないと、「未定義」の発見が遅れる
一見ちゃんとしているように見えるコードでも、
宣言のタイミングと代入のタイミングを意識していないとこんなことが起きます。
let total = price + tax; // price と tax は本当に初期化済み?
console.log(total);
JavaScriptもし price や tax がまだ宣言だけで、
代入(初期化)されていなかったら、
priceやtaxの中身はundefined- 計算結果は
NaN
という、「見た目には一発で分からないバグ」が生まれます。
ここが重要です。
「変数は宣言したか?」と同じくらい、「この時点で値は代入されているか?」を意識する必要がある。
宣言と代入を頭の中で区別しているかどうかが、こういうバグに気づけるかどうかを分けます。
let / const / var と宣言・代入の関係
let の場合
let は「再代入できる変数」を宣言します。
let x; // 宣言(中身は undefined)
x = 1; // 最初の代入(初期化)
x = 2; // 再代入
JavaScript宣言と代入は分けてもいいし、
let x = 1; // 宣言+初期化
x = 2; // 再代入
JavaScriptと書いても OK です。
const の場合
const は、「再代入できない変数」を宣言します。
ひとつ特徴的なのは、
宣言だけ(代入なし)が禁止されている
という点です。
const y; // エラー:初期化が必要
y = 10;
JavaScript必ずこう書く必要があります。
const y = 10; // 宣言+初期化(この一回きり)
JavaScriptつまり、const の場合、
- 宣言
- 最初の代入(初期化)
は、必ず同時に行われます。
その後の再代入はできません。
const y = 10;
y = 20; // エラー:再代入不可
JavaScriptvar の場合(古いが一応)
var も宣言+代入を行うキーワードですが、
var z; // 宣言(中身は undefined)
z = 5; // 代入
JavaScriptや
var z = 5; // 宣言+代入
JavaScriptのどちらもOKです。
ただし、var はスコープや再宣言などの挙動が分かりづらく、
初心者には罠が多いので、
新しいコードでは基本 let / const を使う と考えてください。
ここが重要です。
どのキーワードを使うにせよ、「宣言のタイミング」と「代入のタイミング」を意識しておくことが大事。const は宣言=初期化が必須で、let は宣言だけしてあとで初期化もできる、と整理して覚える。
宣言と代入を意識できるようになるための考え方
変数を見るたびに、「この変数はいつ宣言された?いつ値が入った?」と問う
コードを読むとき、変数に出会うたびに、
「この変数は、どこで宣言されている?」
「この行に来るまでに、ちゃんと値が代入されている?」
と自分に質問してみてください。
例えば:
let result;
if (条件) {
result = 10;
}
console.log(result);
JavaScriptこのコードを見たら、
- result は上で宣言されている
- でも条件によっては、代入が実行されない
- その場合、ここでの result はまだ undefined
という状態が見えてきます。
これが分かるようになると、「宣言しただけで代入していない危険な変数」を早めに見つけられるようになります。
「宣言だけ」か、「宣言+初期化」か、書き分ける
練習として、自分のコードの中で、
- 「宣言だけ」している変数
- 「宣言と同時に初期化」している変数
を意識して書き分けてみてください。
本当に「あとで値が決まる」ものだけを「宣言だけ」にする。
それ以外は、意味のある初期値でちゃんと初期化する。
たとえば:
let total = 0; // すぐに 0 から使い始めるなら初期化したほうが安全
let selectedUser = null; // 「まだ選ばれていない」ことを明示
let temp; // 本当に「あとで決まる」一瞬の変数なら宣言だけもアリ
JavaScriptここが重要です。
宣言と代入を意識して書くと、「この変数は最初から意味のある値が入っているのか」「途中で変わるのか」が、コード上で自然と浮かび上がってくる。
それが、そのままバグを減らす力になります。
まとめ:宣言と代入の違い(初心者向けの核心)
最後に、コンパクトに整理します。
宣言:変数という「名前付きの箱」を作ること。let x; のように書くと、x は「存在する」が、中身は undefined。
代入:その変数の中に値を入れること。
最初の代入(初期化)も、その後の再代入(上書き)も「代入」。
let x = 10; は、「宣言」と「最初の代入(初期化)」を同時にやっている形。
宣言だけで初期化していない変数は undefined になり、そのまま使うと NaN や「undefined」と表示されるなど、バグの原因になりやすい。
const は「宣言と同時に初期化が必須」で、その後の再代入は禁止。let は「宣言だけ」→「あとで代入」もできるが、初期化抜けに注意。
ここが重要です。
変数を見るたびに、「この変数はどこで宣言された?いつ最初の値が入った?今の時点で必ず値が入っていると言い切れる?」と考える癖をつけると、宣言と代入の違いが身体感覚として身につき、バグに強いコードが書けるようになります。
もしよければ、小さな練習として、
let a;
let b = 5;
let c;
a = 3;
console.log(a, b, c);
c = a + b;
console.log(c);
JavaScriptを自分で追いかけてみてください。
「この行の時点で a / b / c は何になっているか?」を一行ずつ紙に書いていくと、
宣言と代入、そして undefined の関係がかなりクリアに見えてくるはずです。
