unrealMan’s blog

IT関連の奮闘記を備忘録がてら記載していきます!

【javaScript】変数スコープの整理

スコープの種類

グローバルスコープ

プログラムのどこからでもアクセス可能なスコープ。
プログラムのトップレベルで宣言された変数(グローバル変数)はこのスコープを持つ。

ローカルスコープ(関数スコープ/ブロックスコープ)

グローバル変数以外は、ローカルスコープを持つローカル変数です。
関数スコープとブロックスコープの2つに分けられます。

関数スコープ

関数ごとのスコープ。
関数内で宣言した変数は、関数の内側からのみアクセス可能なローカル変数になります。
※仮引数も同じく関数スコープを持ちます。

function fn(arg) {
  // 仮引数 arg は参照できる
  console.log(arg); // => 1
}
fn(1);
ブロックスコープ

ブロック({})ごとのスコープ。
ブロック内で宣言した変数は、ブロックの内側からのみアクセス可能なローカル変数になります。
※仮引数も同じく関数スコープを持ちます。

for (let i = 0; i < 5; i++) {
  // 仮引数 i は参照できる
  console.log(i);
}

変数キーワードの種類

var

・関数スコープを持つ。
つまり、ifブロック内の宣言であろうと宣言された関数のどこからでもアクセスできる。

(function() {
  if (true) {
    var x = 'hoge';
  }
  console.log(x); // => hoge
}());

・変数を宣言する前に参照してもエラーとならない。

console.log(s); // => undefined
var s = "hoge";

・再定義可能

var x = "hoge";
var x = "moge";
console.log(x); // => moge

これは、意図せずに同じ変数名で定義してもエラーとならずに、値を上書きしてしまう。

let

ブロックスコープを持つ。
つまり、letで宣言された変数にアクセスできるのは、それらの変数が宣言されたブロック(またはサブブロック)の内側のみとなる。
・変数がvarに比べてはるかに予測可能なものとなり、ブロック外での使用されたことによるバグの紛れ込みがなくなる。
・変数を宣言する前に参照するとエラーとなる。

console.log(t); // => ReferenceError: Cannot access 't' before initialization
let t = "moge";

・再定義不可能

let x;
let x; // => SyntaxError: Identifier 'x' has already been declared

const

・定数。変更不可。
・再代入が必要ないときはconstを使う。


以上です。