今回はJavaScript
の変数型var
・let
・const
について、var
の使用が非推奨とされる理由について、各変数宣言の特徴や巻き上げなどの観点からまとめていきます。
JavaScriptの変数宣言の特徴
JavaScript
の変数宣言にはvar
・let
・const
の3種類があります。
var a;
let b;
const c;
それぞれの特徴について見てみましょう。
var | let | const | |
---|---|---|---|
再代入 | ○ | ○ | × |
再宣言 | ○ | × | × |
スコープ | 関数スコープ | ブロックスコープ | ブロックスコープ |
再代入
再代入とは宣言した変数に、再度値を代入することです。var
・let
は再代入が可能ですが、const
は不可能です。
var a = 1;
a = 2;
//再代入可能
let b = 1;
b = 2;
//再代入可能
const c = 1;
c = 2;
//エラーが起きる
//Uncaught TypeError:
ここで、const
は単なる再代入はできませんが、オブジェクト型の中身を変更することができます。
const obj = {
id: 01;
name: "オブジェクト1";
}
obj.name = "オブジェクト2";
//オブジェクトの中身は変えられる
再宣言
再宣言とは、宣言した変数名を再度宣言し直すことです。var
は再宣言が可能ですが、let
・const
は不可能です。
var a = "宣言1回目";
var a = "宣言2回目";
//再宣言可能
let b = "宣言1回目";
let b = "宣言2回目";
//エラーが起きる
//Uncaught SyntaxError:
const c = "宣言1回目";
const c = "宣言2回目";
//エラーが起きる
//Uncaught SyntaxError:
スコープ
スコープとは関数を呼び出すことが出来る範囲のことです。var
のスコープは関数スコープであり、ある関数内で宣言した変数は、その関数のどこからでも呼び出すことができます。
function x() {
var a = 1;
console.log(a);
{
a = 2;
console.log(a);
}
console.log(a);
}
//出力結果
//1
//2
//2
対して、let
・const
のスコープはブロックスコープです。関数スコープと違い、関数内の記述位置でスコープから外れます。
function x() {
let b = 1;
console.log(b);
{
b = 2;
console.log(b);
}
console.log(b);
}
//出力結果
//1
//2
//1
変数の巻き上げについて
JavaScript
には変数の巻き上げという独特の特徴を有しています。関数内で宣言された変数は、関数の先頭で宣言したとみなされます。
var x = "Test1";
function func() {
console.log(x); // undefinedが出力される
var x = "Test2";
console.log(x); // Test2
}
上のコードではx
の宣言前にconsole.log
で記述していて、一見Test1
が出力される気がしますが、undefined
(未定義)が出力されます。これが変数の巻き上げで、上のコードは実行時には下のコードのように見なされます。
var x = "Test1";
function func() {
var x; //変数の巻き上げ
console.log(x); // undefinedが出力される
x = "Test2";
console.log(x); // Test2
}
varの利用が非推奨な理由
上で述べた様に、var
は再宣言・再代入が可能であること、スコープの範囲が広いこと、巻き上げの特徴を持つことから、変数の値が意図しない影響を受けてしまう可能性があります。
上記のような仕様から、特に複雑なソースコードではvar
を使用を避けるべきであると言えます。
基本的には変数宣言にはconst
を使い、const
だけでは難しい場合にlet
を使うようにしましょう。例えばfor文などは使うのはlet
ですね。以上で記事を終わりにします。