未経験からエンジニアになりたい人必見!
おすすめプログラミングスクール3選!

【JavaScript】スコープ(Scope)について理解しよう

本記事では、JavaScriptのスコープについてサンプルコードを載せて分かりやすく解説しています。

JavaScriptの学習におすすめ参考書
改訂新版JavaScript本格入門

参考書が苦手な人はUdemyの動画がおすすめ
ガチで学びたい人のためのJavaScriptメカニズム

作成者 CodeMafia
学習時間 20.5時間
受講者数 16,593人
レビュー (2,383件)

スコープとは

JavaScriptのスコープとは、値と式が参照できる有効範囲のことを指します。スコープには大きく分けて「グローバルスコープ」「ローカルスコープ」の2つがあり、ローカルスコープは「関数スコープ」「ブロックスコープ」の2つに分類できます。

スコープ構造
| --- グローバルスコープ
| --- ローカルスコープ
      | --- 関数スコープ
      | --- ブロックスコープ

それぞれのスコープの特徴についてコードを載せながら解説していきます。

グローバルスコープ

グローバルスコープとは、プログラムのトップレベルで宣言された変数が持つスコープです。

グローバルスコープの変数は、グローバル変数とも言われプログラムのどこからでも参照することが可能です。

JavaScript
var apple = "りんご"

console.log(apple); // -> りんご

function getFruits(){
  console.log(apple); // -> りんご
}
getFruits();

グローバルスコープとWindowオブジェクトについて

JavaScriptにはデフォルトで用意されているWindowオブジェクトがあります。グローバル変数は宣言されると、Windowオブジェクトのプロパティとして値が追加されます。

Windowオブジェクト自体がグローバルスコープのため、window.を省略した書き方でも同じ結果が出力されます。

JavaScript
var color = "赤色"

console.log(color); // -> 赤色
console.log(window.color); // -> 赤色
windowオブジェクトに追加

ローカルスコープ

冒頭で話した通り、ローカルスコープは「関数スコープ」「ブロックスコープ」の2つに分類されます。

それぞれのスコープについて解説します。

関数スコープ

まず始めに関数スコープについて解説します。関数スコープとは名前の通り、関数内で宣言された変数が持つスコープになります。

HTML
function scopeFunc(){
  let orange = "オレンジ";
  console.log(orange) // -> オレンジ
}

console.log(orange); // -> Uncaught ReferenceError: orange is not defined

関数内で変数を宣言した場合、その関数内であれば変数を参照することができますが、関数の外から参照しようとするとその値は存在しない「Uncaught ReferenceError: 変数名 is not defined」とのエラーが返ってきます。

ブロックスコープ

続いてブロックスコープについて解説します。ブロックスコープとは{}内で宣言された変数が持つスコープになります。if文やfor文などが該当します。

{}内で宣言された変数ということは、関数スコープもブロックスコープなの?と疑問に思われた方もいらっしゃると思いますが、関数スコープとブロックスコープは別物になります。

関数スコープは{}に囲われていますが、functionで関数宣言をしているため関数スコープとしての役割を持ちます。

ブロックスコープは関数スコープと同様に、ブロックスコープ内で宣言された変数はそのブロック内であれば参照することができますが、ブロックの外から参照しようとするとその値は存在しない「Uncaught ReferenceError: 変数名 is not defined」とのエラーが返ってきます。

JavaScript
{
  let banana = "バナナ";
  console.log(banana); // -> バナナ
}

console.log(banana); // -> Uncaught ReferenceError: banana is not defined

ブロックスコープで変数を宣言する注意点

ブロックスコープ内で変数を宣言する際には、letまたはconstを使用します。varを使用して変数を宣言した場合、ブロックスコープは生成されないので注意しましょう。

JavaScript
{
  var banana = "バナナ";
  console.log(banana); // -> バナナ
}

console.log(banana); // -> バナナ

ブロックスコープで関数を宣言する注意点

ブロックスコープ内で「function 関数名」の書き方で関数宣言をした場合、ブロックスコープ外でも呼び出すことが可能になってしまいます。

ブロックスコープ内で関数宣言をする時には、変数の中に関数を代入する形で記述することでブロックスコープ外からの呼び出しはできないようにすることができます。

JavaScript
/*** 間違った使い方 ***/
{
  function helloWorld(){
    console.log('Hello World');
  }  
}
hello World() // -> Hello World

/*** 正しい使い方 ***/
{
  const helloWorld = function () {
    console.log("Hello World");
  };
}
helloWorld(); // -> Uncaught ReferenceError: helloWorld is not defined