JavaScriptを勉強し始めると、変数宣言で「var」「let」「const」が出てきますよね。
でも最近のコードでは「var」ってあまり見かけない…?
「え、varってもう使わないの?使っちゃダメなの?」
そんな疑問にお答えします!
🔍 var の正体とは?
JavaScript初期からある古い変数宣言
JavaScriptが生まれたのは1995年。
当時はWebページに動きをつけるための軽いスクリプト言語として設計されていて、まだまだ今ほどの大規模開発を想定していませんでした。
その時代のJavaScriptの仕様では、変数を宣言する方法はvarだけでした。
つまり、varはJavaScriptの「元祖変数宣言」と言えます。
特徴
varは再宣言・再代入可能な変数です。
//変数定義
var name = "田中";
//再宣言 nameという変数を再び定義
var name = "佐藤";
//再代入 変数に上書き
name = "伊藤";
これだけ見たら一見便利にもおもえますね?
しかし、varには次のような危険性が含まれています。
varが避けられる3つの理由

① スコープがブロックではなく関数単位でわかりづらい
◆ スコープ(変数の有効範囲)とは?
・スコープとは、変数や関数などが「どこからアクセスできるか」を決める範囲のことです。
◆ ブロックスコープと関数スコープの違い
ブロック(block)
{}
で囲まれた部分を指します。if
文や for
ループ、while
ループなどでよく使います。
例:
if (true) {
// ここがブロック
let a = 10;
}
// ブロック外からは a にアクセスできない
関数(function)
function 関数名() { … }
のように宣言して実行できるまとまりです。呼び出す(コールする)ことで中の処理が実行されます。
例:
function greet() {
const message = "こんにちは";
console.log(message);
}
// 関数の外からは message にアクセスできない
varは関数スコープ(Function Scope)
var
で宣言した変数は「関数の中だけで有効」ですが、ブロック({}
)では区切られません。つまり、if
や for
の中で var x = …
と宣言しても、同じ関数内であれば「外からも見えてしまう」ことになります。
◆ なぜこれがわかりづらいか?
初心者の方は「{}
で囲まれた部分を抜けたら変数は消える」と直感しがちです。しかし var
はブロックをまたいで見えてしまうため、意図しないバグを生みやすいのです。
具体例:
function example() {
if (true) {
var num = 100;
console.log("ブロック内の num:", num); // 100
}
// ブロックを抜けても num は生きている!
console.log("ブロック外の num:", num); // 100 ← えっ?
}
example();
このように、if (true) { … }
の中で var num
を宣言したにもかかわらず、ブロックの外(同じ関数内)で普通に参照できてしまっています。
一方、let
や const
で書くと、ブロックを抜けたら変数は見えなくなります:
function example2() {
if (true) {
let num2 = 200;
console.log("ブロック内の num2:", num2); // 200
}
// num2 はブロック外からは使えない(ReferenceError が起きる)
console.log("ブロック外の num2:", num2); // ReferenceError: num2 is not defined
}
example2();
② 巻き上げ(hoisting)で思わぬバグの元になる
◆ 巻き上げ(hoisting)とは?
JavaScript エンジンはコードを実行する前に「変数宣言だけ」をプログラムの先頭にまとめて解釈する仕組みのことを hoisting(ホイスティング:巻き上げ) と呼びます。
具体的に言うと、var x = 5;
の場合、エンジンは内部的に次のように読み替えます:
var x; // 変数宣言が先に“巻き上げ”られる
x = 5; // 実際の代入は元の位置で行われる
◆ これがバグの元になる理由
宣言前に変数を参照してもエラーにならず、値は undefined
になる
初心者の方は「宣言する前に変数を使うとエラーになる」と思いがちですが、var
の場合は例外です。
例えば:
console.log(score); // undefined ← えっ?エラーじゃないの?
var score = 80;
console.log(score); // 80
上記コードはエンジン内部で次のように処理されます:
var score; // 先に宣言だけが巻き上げられる
console.log(score); // undefined
score = 80; // ここでやっと代入される
console.log(score); // 80
varを使うと
- 宣言前に使うとまったく違う値(
undefined
)が返ってくるから、バグ探しが難しい - どこで何が
undefined
になったのか、わかりにくい
という弱点があります
③ 同じ変数名で再宣言できてしまう(バグの温床)
◆ 変数の再宣言(redeclaration)とは?
再宣言とは、同じ名前の変数をもう一度 var
で宣言できてしまうことです。
var count = 5;
var count = 10; // 同じ名前をもう一度宣言してしまっている
console.log(count); // 10
この状況だと「どこで何を上書きしたのかわからなくなり、バグを生む原因になりがち」です。
再宣言が起きてしまうと
- 途中まで
count = 5
で動いていたはずなのに、別の場所で知らないうちにvar count = 10
としてしまうと、プログラムの動作が突然変わってしまう - コードが大きくなるほど「同じ変数名がどこで再宣言されたのか」探すのに時間がかかる
などの問題点が発生します
まとめ:これからは let / const を使おう!
ここまで紹介してきたように、var
は以下のような特徴を持っています:
- スコープが関数単位で直感的じゃない
- 巻き上げ(hoisting)で予期せぬ挙動が起こる
- 再宣言ができてしまい、バグの温床になる
これらは、コードが読みづらくなったり、知らないうちにバグを生む原因になります。
小さいプログラムなら問題にならなくても、少し複雑になると「なんで動かないの?」と悩むことが増えてきます。
今どきのJavaScriptでは、「var
は使わない」のが当たり前になりつつあります。
代わりに使うのは次の2つ:
let
:値があとで変わる変数に使うconst
:値を変更しない定数に使う(基本はこちらが推奨)
これからJavaScriptを学ぶ人は、まずは var
を使わずに let
/ const
だけで書く練習をしてみましょう!
その方が、後々のバグも減らせて、より安全で分かりやすいコードになりますよ!
コメント