りゅうじの学習blog

学習したことをアウトプットしていきます。

2022年3月18日 りあクトJavaScript varの挙動について

varの挙動についてはJavaScriptPrimerで学んでいましたが、りあクトを読んでいて認識が甘かった挙動があったのでアウトプットします。

var x = 1;

if(true) {
  var x = 2;
  var m = 3;
  console.log(x);
}

console.log(x);
console.log(m);

このコードでの何が出力されるのか?の部分です。

答えは以下です。

var x = 1;

if(true) {
  var x = 2;
  var m = 3;
  console.log(x); // => 2
}

console.log(x); // => 2
console.log(m); // => 3

ちなみにlet を使うとエラーになります。

ポイント

  • var で定義された変数はブロックスコープをすり抜けます。
  • varで定義された変数は関数スコープです。
  • let とここでは使っていないがconst で定義された変数はブロックスコープです。

JavaScriptPrimerにもvarブロックスコープをすり抜けると記述してありましたが

if文を使用したときの挙動の違いを私は認識できていませんでした。(if文はブロックスコープなのですが甘かったです)

いい機会なので関数スコープとブロックスコープを復習します。

関数スコープ

function fn() {
    const x = 1;
    // fn関数のスコープ内から`x`は参照できる
    console.log(x); // => 1
}
fn();
// fn関数のスコープ外から`x`は参照できないためエラー
console.log(x); // => ReferenceError: x is not defined
  • 関数fnの中で定義された変数 x は関数の外で出力しようとするとエラーになります。

このような関数によるスコープの事を関数スコープといいます。

ブロックスコープ

{}で囲んだ範囲をブロックと呼びます。ブロックもスコープを作成します。

ブロック内で宣言された変数はスコープ内でのみ参照できスコープの外側からは参照できません。

// ブロック内で定義した変数はスコープ内でのみ参照できる
{
    const x = 1;
    console.log(x); // => 1
}
// スコープの外から`x`を参照できないためエラー
console.log(x); // => ReferenceError: x is not defined

色んな書籍を読んでいって疑問に感じたところは都度振り返り復習を交えてアウトプットしていきます。

参考

りあクト! 【Ⅰ.言語・環境編】

JavaScriptPrimer 関数とスコープ