読み込み中...

JavaScriptの変数スコープを徹底解説!7つのポイントで理解を深める

JavaScript変数スコープ徹底解説 JS
この記事は約9分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

この記事を読めば、JavaScriptの変数スコープを理解し、作り方や使い方、注意点、カスタマイズ方法などが身に付きます。

初心者の方でも分かりやすい説明とサンプルコードで、JavaScriptの変数スコープをしっかりと理解しましょう。

●JavaScript変数スコープとは

変数スコープとは、変数がアクセス可能な範囲のことです。

スコープを理解することで、変数の使い方がより効率的になり、バグの発生を抑えることができます。

○変数スコープの種類

JavaScriptには主に2つのスコープがあります。

  1. グローバルスコープ -> プログラム全体からアクセスできる変数の範囲
  2. ローカルスコープ -> 関数内でのみアクセスできる変数の範囲

○スコープチェーンとは

スコープチェーンとは、変数にアクセスする際に参照されるスコープの階層構造のことです。

変数を探す際には、現在のスコープから外側のスコープへと順番に検索が行われ、最終的にグローバルスコープまでたどり着きます。

●変数スコープの作り方

○グローバルスコープ

グローバルスコープは、プログラム全体からアクセスできる変数の範囲です。

関数の外で宣言された変数がグローバルスコープになります。

○スコープチェーンとは

スコープチェーンとは、変数にアクセスする際に参照されるスコープの階層構造のことです。

変数を探す際には、現在のスコープから外側のスコープへと順番に検索が行われ、最終的にグローバルスコープまでたどり着きます。

●JavaScriptにおける変数スコープの理解

JavaScriptでプログラミングを行う際、変数スコープの概念を理解することは非常に重要です。

変数スコープとは、その変数がどの範囲で有効であるかを定義するルールです。

これには主に、グローバルスコープとローカルスコープの二種類があります。

○JavaScriptのグローバルスコープ

グローバルスコープは、JavaScriptのプログラム全体でアクセス可能な変数の範囲を指します。

このスコープに属する変数はどの関数の内部からも参照・変更が可能です。

例えば、下記のコードではglobalVarがグローバルスコープで宣言されています。

// グローバル変数
var globalVar = "グローバルスコープ";

function testScope() {
  // この関数の中からglobalVarにアクセスできる
  console.log(globalVar);
}

testScope(); // 出力: "グローバルスコープ"

この例では、globalVarは関数の外で宣言されており、どの関数からもアクセスが可能です。

○JavaScriptのローカルスコープ

対照的に、ローカルスコープは関数内で宣言された変数に限定されるスコープです。

これらの変数は、その関数の外部からはアクセスすることができません。

下記の例では、localVarは関数localScope内で宣言されています。

function localScope() {
  // ローカル変数
  var localVar = "ローカルスコープ";
  console.log(localVar);
}

localScope(); // 出力: "ローカルスコープ"
console.log(localVar); // エラー: localVarはローカル変数であるため、関数外からはアクセス不可能

このケースでは、localVarlocalScope関数の内部でのみ利用可能であり、外部からは参照できません。

●JavaScriptの変数スコープ

JavaScriptでコーディングを行う際、変数スコープの知識は非常に役立ちます。

ここでは、グローバルスコープとローカルスコープ、そしてブロックスコープを理解するための具体的なサンプルコードとその説明を紹介します。

○サンプルコード1:グローバルとローカルの違いを理解する

このサンプルでは、JavaScriptにおけるグローバルスコープとローカルスコープの基本的な違いを表しています。

var globalVar = "グローバル変数";

function showVars() {
  var localVar = "ローカル変数";
  console.log(globalVar); // 出力: "グローバル変数"
  console.log(localVar); // 出力: "ローカル変数"
}

showVars();
console.log(globalVar); // 出力: "グローバル変数"
console.log(localVar); // エラー: localVarは関数内で宣言されているため、外部からはアクセス不可

このコードでは、関数内で定義されたlocalVarはその関数の外部からはアクセスできないことが示されています。

○サンプルコード2:スコープチェーンの理解

下記のサンプルコードは、関数内部でスコープチェーンがどのように機能するかを表しています。

var outerVar = "外側の変数";

function outerFunction() {
  var innerVar = "内側の変数";

  function innerFunction() {
    console.log(outerVar); // 出力: "外側の変数"
    console.log(innerVar); // 出力: "内側の変数"
  }

  innerFunction();
}

outerFunction();

この例では、内部の関数が外側の関数の変数にアクセスできることを表しています。

○サンプルコード3:ブロックスコープとlet/constの利用

最後のサンプルでは、ブロックスコープとlet/constを使った変数宣言の違いを説明します。

function blockScopeExample() {
  if (true) {
    var varVar = "varで宣言";
    let letVar = "letで宣言";
    const constVar = "constで宣言";
  }

  console.log(varVar); // 出力: "varで宣言"
  console.log(letVar); // エラー: letVarはブロックスコープ内で宣言されているため、外部からはアクセス不可
  console.log(constVar); // エラー: constVarも同様にブロックスコープ内でのみアクセス可能
}

blockScopeExample();

このコードは、letconstで宣言された変数がブロックスコープ内でのみ有効であることを示しています。

●注意点

  1. 関数内で宣言した変数はローカルスコープになるため、関数外からアクセスできません。
  2. letconstで宣言した変数はブロックスコープになり、そのブロック内でのみアクセス可能です。
  3. varで宣言した変数は巻き上げ(hoisting)が発生し、変数宣言前にアクセスできてしまいます。

●JavaScriptにおける変数の巻き上げ(Hoisting)への対処法

JavaScriptの変数スコープを完全に理解するには、「変数の巻き上げ(hoisting)」という現象とその対処法を知ることが重要です。

変数の巻き上げは、変数宣言がコードの最上部に「巻き上げられる」かのように振る舞うJavaScriptの特性です。

下記のサンプルコードは、この概念とその対処法を表しています。

○サンプルコード4:変数の巻き上げとその回避

このサンプルでは、変数の巻き上げとそれを避ける方法を紹介しています。

function hoistingExample() {
  console.log(hoistedVar); // 出力: undefined(巻き上げが発生)
  var hoistedVar = "巻き上げされる変数";

  console.log(noHoistingVar); // エラー: noHoistingVarは未定義(巻き上げが発生しない)
  let noHoistingVar = "巻き上げされない変数";
}

hoistingExample();

このコードでは、varで宣言されたhoistedVarが未定義の状態で参照されているのに対し、letで宣言されたnoHoistingVarは参照する前に宣言する必要があります。

対処法として、letconstを使用して変数を宣言することで、巻き上げを防ぐことが可能です。

これにより、変数が宣言される前に誤って使用されるリスクを減らし、より予測可能で安全なコードを書くことができます。

●JavaScriptにおける変数スコープのカスタマイズ:即時関数によるカプセル化

JavaScriptの変数スコープを効果的に管理し、グローバルスコープの汚染を防ぐ方法の一つとして、即時関数(Immediately Invoked Function Expression, IIFE)を使ったカプセル化があります。

これは、特定の変数を関数のスコープ内に閉じ込め、外部からのアクセスを制限するテクニックです。

下記のサンプルコードは、この方法を具体的に表しています。

○サンプルコード5:即時関数を利用した変数のカプセル化

この例では、即時関数を使って変数をカプセル化し、グローバルスコープへの影響を最小限に抑える方法を説明します。

(function () {
  var encapsulatedVar = "カプセル化された変数";
  console.log(encapsulatedVar); // 出力: "カプセル化された変数"
})();

console.log(encapsulatedVar); // エラー: encapsulatedVarは即時関数内で定義されているため、外部からはアクセス不可

このコードでは、encapsulatedVarは即時関数の内部で宣言されており、その外部からはアクセスすることができません。

このような即時関数の使用は、特にライブラリやフレームワークを作成する際に役立ち、グローバルスコープを清潔に保つのに有効です。

まとめ

この記事では、JavaScriptの変数とスコープについて初心者向けに詳しく解説しました。

スコープチェーンやブロックスコープ、巻き上げ(hoisting)といった概念を理解し、注意点や対処法を学びました。

また、カスタマイズ方法として即時関数を使用したカプセル化についても説明しました。

これらの知識を活用して、より安全で効率的なJavaScriptコードを書くことができるようになります。

この記事を読んだことで、JavaScriptの変数とスコープに関する理解が深まったことでしょう。

今後のプログラミングに役立ててください。