これまで変数を宣言する際は var キーワードを使用してきましたが、es2015からは let キーワードと const キーワードで宣言することができるようになりました。
ここでは、それぞれのキーワードで宣言した場合の違いについて学んでいきましょう。
これから var ・ let ・ const の違いを確認していきますが、今後のコーディングは以下の前提で行うようにしましょう。
以下の表は、var ・ let ・ const の違いを一覧にまとめたものです。
var | let | const | |
---|---|---|---|
再宣言 | 可 | 不可 | 不可 |
再代入 | 可 | 可 | 不可 |
スコープの種類 | 関数スコープ | ブロックスコープ | ブロックスコープ |
変数の巻き上げ | undefined | ReferenceError が発生する | ReferenceError が発生する |
varキーワードで宣言した変数は再宣言・再代入をすることができます。
function var_pattern_1() {
// var での再宣言
var value = 1;
var value = 2;
}
function var_pattern_2() {
// var での再代入
var value = 1;
value = 2;
}
varキーワードで宣言したローカル変数は 関数スコープ
となります。
関数スコープの場合は関数内であれば宣言したブロックが異なっていても参照することができます。
function var_pattern_3() {
let isLoop = true;
while(isLoop){
// value 変数を宣言したのちループ処理を抜ける
var value = 1;
isLoop = false;
}
// ブロックスコープが適用されないため value 変数を参照できる
console.log(value); // 1
}
先述の通り、 var キーワードで宣言されたローカル変数は同関数内であれば参照することができます。
実は宣言の前からでも参照することができるのです。
この事象は「巻き上げ(hosting)」と呼ばれています。
以下のサンプルコードでは、1回目のconsole.log()
でパラメーターに value 変数を渡していますが、実行時点では value 変数は宣言されていません。
実行してもエラーは発生しませんが、1回目のconsole.log()
でログに表示されるのはundefined
となります。
function var_pattern_4() {
console.log(value); // undefined
var value = 1;
console.log(value); // 1
}
JavaScriptでは関数内で宣言されたローカル変数は、すべてその関数の先頭で宣言されたものとみなされます。
letキーワードで宣言したローカル変数は再宣言することはできませんが、再代入することはできます。
letキーワードで宣言したローカル変数を再宣言するようにコーディングすると、保存する際に JavaScript の文法が間違っているという意味の構文エラー(SyntaxError)
が発生します。
function let_pattern_1() {
// let での再宣言
// 保存時にエラー発生 構文エラー: SyntaxError: Identifier 'value' has already been declared
let value = 1;
//let value = 2;
}
function let_pattern_2() {
// let での再代入
let value = 1;
value = 2;
}
letキーワードで宣言したローカル変数は ブロックスコープ となります。
ブロックスコープの場合はブロック内であれば宣言したローカル変数を参照することができますが、同じ関数であってもブロック外からは参照することができません。
function let_pattern_3() {
let isLoop = true;
while(isLoop) {
// value 変数を宣言したのちループ処理を抜ける
let value = 1;
isLoop = false;
}
// ブロックスコープが適用されるため value 変数を参照できない
// 実行時にエラー発生 ReferenceError: value is not defined
console.log(value);
}
let キーワードでローカル変数を宣言した場合は変数の巻き戻しは発生しません。
代わりに実行する際に参照する変数が見つからないという意味の 参照エラー(ReferenceError)
が発生します。
function let_pattern_4() {
console.log(value);
let value = 1;
// 実行時にエラー発生 ReferenceError: Cannot access 'value' before initialization
console.log(value);
}
constキーワードで宣言したローカル変数は再宣言・再代入ができません。
constキーワードで宣言したローカル変数は、letキーワードと同じく ブロックスコープ
となります。
そのため、ブロック内であれば宣言したローカル変数を参照することができますが、同じ関数であってもブロック外からは参照することができません。
function const_pattern_3() {
let isLoop = true;
while(isLoop) {
// value 変数を宣言したのちループ処理を抜ける
const value = 1;
isLoop = false;
}
// ブロックスコープが適用されるため value 変数を参照できない
// 実行時にエラー発生 ReferenceError: value is not defined
console.log(value);
}
let キーワードと同様に、const キーワードでローカル変数を宣言した場合は変数の巻き戻しは発生しません。
代わりに実行する際に参照する変数が見つからないという意味の 参照エラー(ReferenceError)
が発生します。
function const_pattern_4() {
console.log(value);
const value = 1;
// 実行時にエラー発生 ReferenceError: Cannot access 'value' before initialization
console.log(value);
}