JavascriptではES5まではすべての変数宣言でvarが使用されてきた。ES6以降登場したletとconstとの違い、適切な使用法について解説します。
スコープ
・letとconstで宣言された変数には、独自のスコープルールが適用される。
if(true){
let a = 'test';
}
//この処理はエラーとなる。
console.log(a);
letで宣言された変数はその変数が宣言されたブロック(またはサブブロック)の内側だけでのみ使用することができるブロックスコープ(block scope)の特性を持つ。つまり特定の関数内などでプライベート変数として扱うことが可能となるため影響範囲を限定的にすることができる。ただしforループに関しては例外となる。
for (let i = 0; i < length; i++) { // i はfor条件式内で宣言されている
console.log(i); // i のスコープはfor ループのブロック内で適用
}
// for ループの外側ではi を参照できないため、以下はエラーになる
console.log(i);
このfor条件式内で宣言されたiがvarで変数宣言されていた場合は、上記のconsole.log(i);は正しく動作することになる。そのため、できるだけforループ条件式内で変数宣言を行う場合はletを使用するようにしましょう。
letとvarのホイスティング(巻き上げ)
letとvarで宣言された変数には、変数宣言が常に先頭で行われたことになる、巻き上げという挙動をとる。スコープの内側では、変数がletではブロック、varでは関数のスコープ全体で適用される。
つまり、スコープ内であれば、変数宣言の前で変数が使用されても正常に動作することになる。varとletのスコープ内挙動の違いは変数宣言前に変数にアクセスした場合、varは未定義、letは例外をスローする点です。
再宣言
varは再宣言可能で、letとconstは再宣言不可で、エラーがでます。
// varの場合
var a = 0;
var a = 1;
console.log(a) // 1
// letの場合
let b = 0;
let b = 1; // SyntaxError: Identifier 'b' has already been declared
// constの場合
const c = 0;
const c = 1; // SyntaxError: Identifier 'c' has already been declared
再代入
varとletは再代入可能で、変数に値を再代入することができる。constは再代入負荷で、再代入した場合エラーを吐く。
// var
var a = 0;
a = 1;
console.log(a) // 1
// let
let b = 0;
b = 1;
console.log(b) // 1
// const
const c = 0;
c = 1; // Assignment to constant variable.