最近、フロントエンドエンジニアのテクニカルテストを受けたのですが、その中で let
と var
の違いを問う問題がありました。数年前、プログラミングを学び始めた頃にしっかり勉強したはずなのに、いざ聞かれるとうまく答えられず、悔しい思いをしました。やっぱり基本をおろそかにしちゃダメですね。ということで、この機会に let
と var
の違いを改めて整理したので、この記事でシェアしていきます。
var の特徴
var
はES6以前から存在する変数宣言方法で、以下の特徴を持っています。
関数スコープで動作する
var
で宣言した変数は、関数のスコープに従います。
function example() {
if (true) {
var x = 10;
}
console.log(x); // 10 (ブロックスコープ外でもアクセス可能)
}
example();
ブロック {}
内で宣言しても関数スコープのため、外でもアクセス可能です。
ホイステングの影響を受ける
var
はホイステング(変数の宣言が自動的に関数やグローバルスコープの先頭に移動する仕組み)の影響を受けます。
function example() {
console.log(y); // undefined(エラーではないがundefinedとなる)
var y = 20;
console.log(y); // 20
}
example();
変数 y
は宣言だけが巻き上げられ、初期化はそのままの位置にあるため、undefined
になります。
let の特徴
ES6で導入された let
は、var
の問題を解決するために設計されました。
ブロックスコープを持つ
let
で宣言した変数は、ブロック {}
内でのみ有効です。
function example() {
if (true) {
let a = 10;
}
console.log(a); // ReferenceError(ブロックスコープ外なのでエラー)
}
example();
ホイステングされるがTDZ(Temporal Dead Zone)が存在する
let
もホイステングされますが、TDZ(一時的デッドゾーン) によって、宣言前にアクセスするとエラーになります。
function example() {
console.log(b); // ReferenceError(宣言前なのでエラー)
let b = 30;
console.log(b);
}
example();
これにより、var
のように undefined
にならず、安全なコードが書けます。
var を使うべきケースはあるのか?
現代のJavaScript開発では、var
の使用は推奨されていません。ほぼすべてのケースで let
または const
を使うのがベストです。
ただし、古いコードのメンテナンスや、レガシーな環境では var
が使われていることもあるため、理解しておくことは重要です。
let を使うべき実践的な理由
実際の開発で let
を使うべき理由を、もう少し具体的なコード例で見てみましょう。
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// 出力: 3, 3, 3(期待通りに動かない)
出力が3, 3, 3
となるのは、var
のスコープが関数スコープであり、ループが終わった後の i
の値が3になっているためです。
対策として let
を使うと、期待通りの結果になります。
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// 出力: 0, 1, 2(期待通り動作)
このように、スコープ管理のミスを防ぐためにも、let
を積極的に使いましょう。
まとめ
特徴 | var | let |
---|---|---|
スコープ | 関数スコープ | ブロックスコープ |
ホイステング | あり(undefined ) | あり(TDZあり) |
再宣言 | 可能 | 不可 |
主な用途 | 旧コードの互換性 | 現代的なJavaScript |
- 基本は
const
を使う(再代入の必要がない場合) - 変数の値を変更する場合は
let
var
は使わない(レガシーコード以外では非推奨)
テストで不意に聞かれても困らないように、let
と var
の違いは頭の片隅に置いておきましょう!