#はじめに
実装でjsを書いている際に、変数宣言(var,let,const)の使い分けが整理できていなかったのでこの機会にまとめておこうと思う。
#var
再宣言・再代入が可能で、初期化なしの宣言が可能。
var x = 1;
console.log(x); //1
x = 2;
console.log(x); //2 再代入
var x = 3; //再宣言
console.log(x); //3
var s; // 初期化なしの宣言
スコープは関数スコープ
変数xは関数のスコープ内でのみ参照できる。
function (){
var x = 0;
console.log(x); //0
}
console.log(x); //error x is not defined
#let
再代入は可能だが再宣言は不可となっている。初期化なしの宣言が可能。
let x = 1;
console.log(x); //1
x = 2;
console.log(x); //2 再代入
let x = 3; //SyntaxError 再宣言はできない
let s; // 初期化なしの宣言
スコープはブロックスコープ
ブロック内で宣言された変数は、スコープ内でのみ参照でき、スコープの外側からは参照できない。
{
let x = 1;
console.log(x); // => 1
}
console.log(x); // => ReferenceError: x is not defined
function fn(){
let x = 1;
console.log(x);
{
let x = 2;
console.log(x);
}
console.log(x);
}
fn()
結果はこんな感じ
// => 1
2
1
#const
再宣言、再代入が不可で、更に初期化なしの宣言が不可。
const x = 1;
console.log(x); //1
const = 2;
console.log(x); //2 TypeError
const x = 3; //SyntaxError 再宣言はできない
const s; //SyntaxError
スコープはlet
と同じくブロックスコープ。
キーワードなしの宣言
var, let, constをつけなくても変数宣言は成立する。ただしグローバルに参照できる変数となるためバグの元となり非推奨。
#変数の巻き上げ
JavaScript の変数に独特な点として、例外を発生させることなく後に宣言した変数を参照できる点がある。これを巻き上げという。
関数内で宣言したローカル変数をすべてundefinedで初期化するということ、その関数の先頭で宣言されたものと見なされるというもの。
例として
var x = 0;
function (){
console.log(x);
var x = 1;
console.log(x);
}
// => undefined
1
#使い分け
varは使わず、let/constを使う。理由として
varは書き換えが可能なこと、巻き上げ時のバグを生み出しやすいことがあげられる。
letやconstを使っていれば、書き換えてしまってもエラーを出してくれるので、バグ発見に繋がりやすい。