TypeScriptで`var`と`let`を使い分ける極意:スコープ、再宣言、テンプレートリテラルまで
TypeScriptにおける var
と let
の違い
スコープ
var
: 関数スコープを持ちます。これは、変数が関数ブロック内で宣言された場合、その関数内でのみ有効となることを意味します。一方、グローバルスコープで宣言されたvar
変数は、プログラム全体でアクセス可能です。
function exampleVar() {
var varVariable = "varスコープ";
console.log(varVariable); // "varスコープ"を出力
}
console.log(varVariable); // エラー: varVariableは定義されていません
let
: ブロックスコープを持ちます。これは、変数がブロック{}
で囲まれた領域内で宣言された場合、そのブロック内でのみ有効となることを意味します。関数スコープとは異なり、グローバルスコープの影響を受けません。
function exampleLet() {
let letVariable = "letスコープ";
console.log(letVariable); // "letスコープ"を出力
}
console.log(letVariable); // エラー: letVariableは定義されていません
再宣言
var
: 同じスコープ内で同じ名前の変数を再宣言することができます。これは、意図せぬ変数の書き換えや予期しない動作の原因となる可能性があります。
function exampleVarRedeclare() {
var varVariable = "初期値";
varVariable = "再代入値";
console.log(varVariable); // "再代入値"を出力
var varVariable = "別の変数"; // 再宣言
console.log(varVariable); // "別の変数"を出力
}
exampleVarRedeclare();
let
: 同じスコープ内で同じ名前の変数を再宣言することはできません。再宣言しようとすると、コンパイラエラーが発生します。これは、変数の重複を防ぎ、コードの読みやすさとメンテナンス性を向上させるために設計されています。
function exampleLetRedeclare() {
let letVariable = "初期値";
letVariable = "再代入値";
console.log(letVariable); // "再代入値"を出力
let letVariable = "別の変数"; // エラー: 'letVariable'はすでに宣言されています
}
exampleLetRedeclare();
使い分け
一般的に、以下の要件に基づいて var
と let
を使い分けることを推奨します。
- 再宣言の可能性がある変数:
let
を使用します。let
は再宣言できないため、意図せぬ変数の書き換えを防ぐことができます。 - グローバルスコープで宣言される変数: どうしてもグローバルスコープで変数を宣言する必要がある場合は、
var
を使用します。ただし、グローバル変数の使用は極力控え、必要な場合のみ使用するように心がけましょう。 - ブロック内で宣言される変数:
let
を使用します。これは、ブロックスコープにより変数のスコープを明確に定義し、意図せぬ変数の書き換えを防ぐことができます。
var
と let
は、それぞれ異なるスコープと再宣言の挙動を持つ変数宣言キーワードです。これらの違いを理解し、適切に使い分けることで、コードの読みやすさ、メンテナンス性、および信頼性を向上させることができます。
近年では、ほとんどの場合 let
を使用する方が一般的です。これは、let
の方が安全で、コードの意図を明確に表現できるためです。
上記に加えて、TypeScript には const
キーワードも存在します。これは、再代入できない定数変数を宣言するために使用されます。
const constVariable = "定数値
例 1: スコープの違い
function exampleScope() {
var varVariable = "グローバル変数"; // グローバルスコープで宣言
console.log(varVariable); // "グローバル変数"を出力
let letVariable = "ブロック変数"; // ブロックスコープで宣言
console.log(letVariable); // "ブロック変数"を出力
}
console.log(varVariable); // "グローバル変数"を出力
console.log(letVariable); // エラー: letVariableは定義されていません
解説
varVariable
はプログラム全体でアクセス可能ですが、letVariable
は関数exampleScope
内でのみ有効です。- この例では、
varVariable
はグローバルスコープで宣言され、letVariable
はブロックスコープで宣言されています。
例 2: 再宣言の可否
function exampleRedeclare() {
var varVariable = "初期値";
console.log(varVariable); // "初期値"を出力
varVariable = "再代入値";
console.log(varVariable); // "再代入値"を出力
let letVariable = "初期値";
console.log(letVariable); // "初期値"を出力
// letVariable = "再代入値"; // エラー: 'letVariable'はすでに宣言されています
}
exampleRedeclare();
var
は同じスコープ内で同じ名前の変数を再宣言できますが、let
は再宣言できません。- この例では、
varVariable
は再宣言され、letVariable
は再宣言しようとするとエラーが発生します。
例 3: デフォルト値
function exampleDefaultValue() {
console.log(varVariable); // "undefined"を出力
console.log(letVariable); // エラー: letVariableは初期化されていません
var varVariable = "初期値";
let letVariable = "初期値";
console.log(varVariable); // "初期値"を出力
console.log(letVariable); // "初期値"を出力
}
// exampleDefaultValue(); // エラー: varVariableは宣言されていません
- この例では、
varVariable
は宣言時にundefined
に初期化され、letVariable
は宣言時に初期化子を指定する必要があります。
テンプレートリテラル
テンプレートリテラルを使用する場合、let
を使用する方が一般的です。これは、let
のブロックスコープにより、テンプレートリテラル内の変数がスコープ内に明確に保持されるためです。
function exampleTemplateLiteral() {
const name = "山田";
const age = 30;
// var を使用すると、age 変数がテンプレートリテラルの外で再宣言されると、予期しない結果になる可能性があります
var message = `私の名前は ${name} で、年齢は ${age} 歳です。`;
console.log(message); // "私の名前は 山田 で、年齢は 30 歳です。"
// let を使用すると、age 変数がテンプレートリテラル内でのみ有効になり、安全に使用できます
let message2 = `私の名前は ${name} で、年齢は ${age} 歳です。`;
console.log(message2); // "私の名前は 山田 で、年齢は 30 歳です。"
}
exampleTemplateLiteral();
for ループ
for
ループ内で変数を宣言する場合、let
を使用する方が一般的です。これは、let
のブロックスコープにより、ループごとに新しい変数が作成されるためです。
function exampleForLoop() {
for (var i = 0; i < 3; i++) {
console.log(i); // 0, 1, 2を出力
}
console.log(i); // 3を出力 (予期しない動作)
for (let j = 0; j < 3; j++) {
console.log(j); // 0, 1, 2を出力
}
// console.log(j); // エラー: jは定義されていません
}
exampleForLoop();
即時実行関数
即時実行関数 (IIFE) 内で変数を宣言する場合、let
を使用する方が一般的です。これは、let
のブロックスコープにより、IIFE 内の変数がグローバルスコープに影響を与えないためです。
(function() {
var varVariable = "IIFE内の変数";
console.log(varVariable); // "IIFE内の変数"を出力
})();
console.log(varVariable); // エラー: varVariableは定義されていません
(function() {
let letVariable = "IIFE内の変数";
console.log(letVariable); // "IIFE内の変数"を出力
})();
console.log(letVariable); // エラー: letVariableは定義されていません
typescript