【JavaScript】varが非推奨な理由とlet・constとの違い
- ES6以降に学び始めたため、
let・constを使うのが当たり前だと思っていた - 古いコードに触れる機会があると
varを散見するが、そもそもなぜこれが非推奨なのか正直理解してなかった
var・let・constの違い
| var | let | const | |
|---|---|---|---|
| 再宣言 | ✅ | ❌ | ❌ |
| 再代入 | ✅ | ✅ | ❌ |
| スコープ | 関数 | ブロック | ブロック |
| ホイスティング時の初期値 | undefined | (設定されない) | (設定されない) |
| グローバル宣言時のスコープ | グローバル | スクリプト | スクリプト |
varが非推奨な理由
予期せぬバグを生み出す可能性があるから。
再宣言できてしまう
var x = 'x1';var x = 'x2';
let y = 'y1';let y = 'y2'; // Uncaught SyntaxError: Identifier 'y' has already been declared
const z = 'z1';const z = 'z2'; // Uncaught SyntaxError: Identifier 'z' has already been declared再代入できてしまう
var x = 'x1';x = 'x2';
let y = 'y1';y = 'y2';
const z = 'z1';z = 'z2'; // Uncaught TypeError: Assignment to constant variable.letでも同じことではある。
ブロックスコープ外からの上書き
function func() { { var x = 'x'; console.log(x); // 'x' } x = 'y'; console.log(x); // 'y'}varのスコープは関数- 上記の例ではブロック内で宣言した
xのスコープは関数のため、ブロック外からでも上書きできている
ホイスティングによる巻き上げ
var x = 'x';
function func() { console.log(x); // undefined
var x = 'y'; console.log(x); // 'y'}func();varで宣言した場合、ホイスティング時にundefinedで初期化されてしまう- 上記の例ではグローバルコンテキストで
xに'x'が代入されるが、funcのコンテキストが生成されたタイミングでホイスティングされ、関数の実行前にxにundefinedが代入されてしまう
グローバルオブジェクトの上書き
var console = 'x';console.log('x'); // Uncaught TypeError: console.log is not a function- グローバルコンテキスト内で
varで宣言すると、グローバルスコープ (windowオブジェクトのプロパティ) に値が保持されるlet・constはスクリプトスコープとして保持される
- 上記の例では本来
windowに生えているconsoleが上書きされ参照できていない
参考