# Javascript var let const 変数宣言の違い
今まで var と let は一緒、const は定数となんとなく使い分けていたが、これからなんとなくを卒業します。
const var let の違い
const | let | var | |
|---|---|---|---|
| ES バージョン | ES6 以降 | ES6 以降 | すべてバージョン |
| 再宣言 | × | × | ○ |
| 再代入 | × | ○ | ○ |
| スコープ | ブロック | ブロック | 関数 |
| ホイスティング | エラー | エラー | undefined |
| グローバル宣言 window 属性 | × | × | ○ |
var は ECMAScript のすべてのバージョンに対応していますが、const と let は ECMAScript 6 以降しか使えません。なので、IE など古いブラウザーで const let 使ってたらエラーで javascript が動きません。
# var 宣言
var message;
// undefined
var message = "hello";
// hello
message = 1;
// 問題なく動くが、非推薦
文字列から数字に代入してもエラーなくプログラム動きます。このような途中から変数タイプを変更することは ECMAScript 非推薦になります。動くけど
# var 宣言スコープ
var 宣言スコープによってエラーになる場合があります。
function helloworld() {
var message = "hi"; // スコープ変数
}
helloworld();
console.log(message); // エラー
グローバル変数宣言
関数の中でグローバル変数を宣言することができますが、メンテナンスが難しくなり、エラー発生しやすくなります。
# var 宣言優先
var 宣言は自動的に関数の上に昇格されるが、let はされない
function foo() {
console.log(age);
var age = 26;
}
foo(); // undefined
ECMAScript 実装時は以下のソースと同等
function foo() {
var age;
console.log(age);
age = 26;
}
foo(); // undefined
なので、上記のコードはエラーになりません。
let なら ReferenceError になります。
# let 宣言
let と var の使い方はほとんど一緒で、違いは let の宣言範囲はブロックスコープ内、var の宣言は関数スコープ内になります。
if (true) {
var name = "Matt";
console.log(name); // Matt
}
console.log(name); // Matt
if (true) {
let age = 26;
console.log(age); // 26
}
console.log(age); // ReferenceError: age 未定義エラー
宣言スコープ以外のところから変数使おうとしたら、ReferenceError になります。
重複宣言は SyntaxError になります。
var name;
var name; // SyntaxError
let age;
let age; // SyntaxError
var name;
let name; // SyntaxError
let age;
var age; // SyntaxError
同じスコープではなければ、SyntaxError エラーになりません。
var name = "Nicholas";
console.log(name); // 'Nicholas'
if (true) {
var name = "Matt";
console.log(name); // 'Matt'
}
console.log(name); // 'Matt'
let age = 30;
console.log(age); // 30
if (true) {
let age = 26;
console.log(age); // 26
}
console.log(age); // 30
# var let グローバル宣言時の違い
var name = "Matt";
console.log(window.name); // 'Matt'
let age = 26;
console.log(window.age); // undefined
# for 文の中の var と let の違い
let はブロックスコープ内のみのため for 文の外ではリファレンスエラーになります。
// var
for (var i = 0; i < 5; ++i) {
// 処理
}
console.log(i); // 5
// let
for (let i = 0; i < 5; ++i) {
// 処理
}
console.log(i); // ReferenceError:
// varの落とし穴
for (var i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0);
}
// 出力 5 5 5 5 5
# const 宣言
const は let の使い方は基本的に一緒ですが、違いは一度代入した値は変更できないこと、宣言最初から値に代入する必要であること。
const age = 26;
age = 36; // TypeError
代入しようとしたら TypeError
重複宣言は SyntaxError になります。
宣言範囲は let と一緒でブロックになります。
const name = "Matt";
if (true) {
const name = "Nicholas";
}
console.log(name); // Matt
# まとめ
ES6 は 2015 年公開してから、今は各ブラウザが対応済みで兼用性の心配なく使えるようになりましたが、古いブラウザーに対応する必要があるプロジェクトは気をつけなければなりません。
var の定義が厳密でないため、大きいプロジェクトではバグの原因になります。ES6 で追加された const と let は明確に使えるスコープ規定しているため、var よりメンテナンスしやすくなります。変動ない値は const それ以外は let 使うこと!古いブラウザーのみ var 使う!
ES6 とは
2015 年に標準化された ECMASCript 6th Edition のこと、正式名称は ES2015 です。