JavaScript

ブロックスコープとは?var,let,constの違いについて解説!【JavaScript】

JavaScriptはES2015(またはES6)で追加されたブロックスコープの導入について解説します。

var,let,constは似てるけど何が違うかわからない!という方におすすめの記事です。

ブロックスコープを理解することで、より安全で効率的なコードの記述が可能になります。

1. ブロックスコープとは?

ブロックスコープは、変数や定数のスコープ(有効範囲)をブロック({}で囲まれた部分)に限定する仕組みです。

従来のJavaScriptでは、varキーワードを使って変数を宣言すると、その変数のスコープは関数スコープでした。

関数スコープでは、ブロック内で宣言した変数もブロック外からアクセスできる可能性がありました。

しかし、ES2015ではletおよびconstキーワードが導入されブロックスコープが利用可能になりました。

これにより、ブロック内で宣言した変数はそのブロック内でのみ有効になり、ブロック外からのアクセスが制限されます。

2. var,let,constの違いについて

“let”、”var”、および”const”は変数宣言のためのキーワードです、

それぞれ異なるスコープや再代入のルールを持っています

“var”はES5以前の古いスタイルの変数宣言であり、”let”と”const”はES6以降のブロックスコープを持つモダンな変数宣言です。

1. var

“var”は、ES5(ES2009)以前のJavaScriptで使われていた変数宣言のキーワードです。以下に、”var”の特徴を説明します。

  • 変数のスコープ:関数スコープ(function scope)を持ちます。つまり、変数は関数内で宣言されると、その関数内でのみ有効です。
  • 変数の巻き上げ(hoisting):変数の宣言部分が関数の先頭に巻き上げられるため、宣言前に変数を使用することができます。
  • 再代入:”var”で宣言した変数は再代入が可能です。
function exampleVar() {
  if (true) {
    var x = 10;
    console.log(x); // 出力: 10
  }
  console.log(x); // 出力: 10(関数スコープ内で有効)
}

2. let

“let”は、ES6(ES2015)以降で導入されたブロックスコープを持つ変数宣言のキーワードです。以下に、”let”の特徴を説明します。

  • 変数のスコープ:ブロックスコープ(block scope)を持ちます。つまり、変数はブロック({}で囲まれた範囲)内で宣言されると、そのブロック内でのみ有効です。
  • 変数の巻き上げ:”let”で宣言した変数は巻き上げられず、宣言前に変数を使用するとエラーになります。
  • 再代入:”let”で宣言した変数も再代入が可能です。
function exampleLet() {
  if (true) {
    let x = 10;
    console.log(x); // 出力: 10
  }
  // ブロック外からはxにアクセスできない
  console.log(x); // エラー: x is not defined
}

3. const

“const”は、ES6(ES2015)以降で導入されたブロックスコープを持つ定数(再代入不可)の宣言のキーワードです。以下に、”const”の特徴を説明します。

  • 変数のスコープ:ブロックスコープ(block scope)を持ちます。つまり、定数はブロック内で宣言されると、そのブロック内でのみ有効です。
  • 変数の巻き上げ:”const”で宣言した変数は巻き上げられず、宣言前に変数を使用するとエラーになります。
  • 再代入:”const”で宣言した定数は再代入ができません。
function exampleConst() {
  if (true) {
    const x = 10;
    console.log(x); // 出力: 10
  }
  // ブロック外からはxにアクセスできない
  console.log(x); // エラー: x is not defined
}

3. ブロックスコープの具体例と活用

ブロックスコープの導入により、コードの安全性と可読性が向上します。

具体例として、ループ変数のスコープをブロック内に限定することができます。

// 従来のJavaScriptでは、ループ変数iが関数スコープで宣言されているため、ループ終了後もアクセス可能でした
function traditionalLoopExample() {
  for (var i = 0; i < 5; i++) {
    // 何らかの処理
  }
  console.log(i); // 出力: 5
}

// ES2015のブロックスコープを使った場合、ループ変数iのスコープをforループのブロック内に限定できます
function blockScopedLoopExample() {
  for (let i = 0; i < 5; i++) {
    // 何らかの処理
  }
  console.log(i); // エラー: i is not defined
}

4. ブロックスコープの注意点

ブロックスコープを活用する際に注意すべき点もあります。

特に、同じ変数名を使ったブロック内のネストにおいて、スコープの階層によって変数の値が上書きされる場合があります。

function nestedScopeExample() {
  let x = 10;

  if (true) {
    let x = 20; // ブロック内でのみ有効な新しい変数xが宣言される(親スコープのxは影響を受けない)
    console.log(x); // 出力: 20
  }

  console.log(x); // 出力: 10(親スコープのxは影響を受けない)
}

まとめ

ES2015に導入されたブロックスコープは、letおよびconstキーワードを使って宣言した変数や定数のスコープをブロック内に限定します。

これにより、変数の衝突を防ぎ、コードの安全性と可読性が向上します。

関数スコープとの違いを理解して、適切にブロックスコープを活用しましょう。