JavaScriptの変数宣言
-
var、let、constの3つの宣言方法がある -
varはJavaScriptリリース当初からある宣言方法 -
letとconstはJavaScriptの最新標準仕様に採択されたES2015で追加された宣言方法 - 3つの違いは 再宣言の可否、再代入の可否、スコープ、ホイスティング の4点
3つの変数宣言の違い(結論)
| var | let | const | |
|---|---|---|---|
| 再宣言 | ○ | × | × |
| 再代入 | ○ | ○ | × |
| スコープ | 関数 | ブロック | ブロック |
| ホイスティング | ○ | undefined | エラー |
先に結論を提示してしまうと上表の通りです。
ここからは実際にコードを書いて挙動の違いを確認していきます。
再宣言
再宣言:一度宣言した変数を再度宣言すること。
/* var */
var sushi = 'maguro';
console.log(sushi) // => maguro
var sushi = 'ikura';
console.log(sushi) // => ikura
/* let */
let sushi = 'maguro';
console.log(sushi) // => maguro
let sushi = 'ikura'; // Uncaught SyntaxError: Identifier 'sushi' has already been declared
/* const */
const sushi = 'maguro';
console.log(sushi) // => maguro
const sushi = 'ikura'; // Uncaught SyntaxError: Identifier 'sushi' has already been declared
-
varは再宣言が可能 -
letとconstは再宣言の時点でエラー
再代入
再代入:既に値が入っている変数に再度値を代入すること。
/* var */
var sushi = 'maguro';
console.log(sushi) // => maguro
sushi = 'ikura';
console.log(sushi) // => ikura
/* let */
let sushi = 'maguro';
console.log(sushi) // => maguro
sushi = 'ikura';
console.log(sushi) // => ikura
/* const */
const sushi = 'maguro';
console.log(sushi) // => maguro
sushi = 'ikura'; // Uncaught TypeError: Assignment to constant variable.
-
varとletは再代入が可能 -
constは再代入の時点でエラー
スコープ
スコープ:直訳すると scope:範囲 のことで、「変数のスコープ」とは「変数が使用出来る範囲」のことを指す。JavaScriptのスコープにはグローバルスコープとローカルスコープの2種があり、ローカルスコープには関数スコープとブロックスコープの2種がある。(詳細は割愛)
/* var */
var sushi = 'maguro';
if (true) {
console.log(sushi); // => maguro
var sushi = 'ikura';
console.log(sushi); // => ikura
}
console.log(sushi); // => ikura
/* let */
let sushi = 'maguro';
if (true) {
console.log(sushi); // => maguro
let sushi = 'ikura';
console.log(sushi); // => ikura
}
console.log(sushi); // => maguro
/* const */
const sushi = 'maguro';
if (true) {
console.log(sushi); // => maguro
const sushi = 'ikura';
console.log(sushi); // => ikura
}
console.log(sushi); // => maguro
-
varは関数スコープなので、ブロック外で宣言された変数に対してブロック内で再宣言が出来てしまう。 -
letとconstはブロックスコープなので、ブロックの内外で変数宣言は区別される。
ホイスティング
ホイスティング:コンテキスト内で宣言した変数定義をコード実行前にメモリに配置すること。巻き上げともいう。
/* var */
sushi = 'maguro';
console.log(sushi) // => maguro
var sushi;
console.log(sushi) // => maguro
/* let */
sushi = 'maguro';
console.log(sushi) // => maguro
let sushi;
console.log(sushi) // undefined
/* const */
sushi = 'maguro';
console.log(sushi) // => maguro
const sushi; // Uncaught SyntaxError: Missing initializer in const declaration
-
varは変数宣言をする前に変数に入れた値がそのまま変数宣言時の値に引き継がれている。 -
letはundefined、つまり「変数宣言はされているけど値が定義されていませんよ」の状態。 -
constは変数宣言時に値の定義も必要なので、「値が定義されていませんよ」の状態。
まとめ
-
varはミスリーディングによる意図せぬ変数使用が起こり得るので使うべきではない - 変数宣言は大人しく
constを使おう - 再代入が必要な場合に限り
letを使おう
(以前の案件のソースコードは全ての変数がvarで宣言されていたけど、良い「悪い例」だったなあ、と…。)