【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
が上書きされ参照できていない
参考