JavaScriptのスコープについて理解を深める

JavaScript

スコープとは

JavaScriptにおけるスコープとは、関数や変数の有効範囲のことを指します。

スコープによってその関数や変数がどこから参照可能なのかが定義されます。

JavaScriptの関数や変数は、定義されたスコープ内でのみ参照することができ、スコープ外から参照することはできません。

では、なぜJavaScriptの関数や変数にスコープが必要なのでしょうか。

スコープの役割

小規模な開発であればスコープの恩恵を感じにくいかもしれません。

少ないコードであれば、一意な関数名や変数名を命名することは容易ですし、それぞれの影響範囲についてもある程度把握できるでしょう。

しかし、より大規模な開発を行う際にはしっかりとスコープを意識してコーディングを行い、保守性の高いコードを書く必要が出てきます。

関数名や変数名の競合を避けることができる

JavaScriptでは、同じ関数名・変数名であっても、スコープが違えば別の関数・変数として扱われます。

もしスコープがなければ、プログラム内の関数名・変数名がそれぞれ全て異なる必要があります。

しかし、JavaScriptではスコープが違えば同じ関数名や変数名でも問題ないので、判別のために長い名前をつける必要があまりありません。

そのため、関数・変数の命名にかかる労力が軽減されたりコードが見やすくなったりするメリットがあります。

保守性の高いコードが書ける

関数や変数の影響範囲が限定されることにより、それぞれの関数・変数にバグの原因があった時の修正や、仕様を変更する際に他の処理への予期せぬ影響を防ぐことができます。

もちろん、関数や変数を細かく定義しぎると多くの箇所を修正する必要があるので注意が必要ですが、適切に関数や変数の影響範囲を限定させることにより保守性の高いコードを書くことができます。

JavaScriptのスコープの種類

JavaScriptには大きく二つのスコープがあり、それぞれブロックスコープローカルスコープと呼ばれます。

また、ローカルスコープの中に関数スコープブロックスコープがあります。

以前まではローカルスコープ=関数スコープでしたが、ES6(ES2015)でブロックスコープが追加され、よりスコープを便利に扱うことができるようになりました。

グローバルスコープ

グローバルスコープはもっとも広いスコープであり、プログラム内のどこからでも参照することができます。

関数等に全く含まれていない箇所で宣言したり、varやlet、constなどを使用せずに宣言するとブロックスコープになります。

また、ブロックスコープの関数・変数をグローバル関数・グローバル変数と呼び、それぞれはwindowオブジェクトのプロパティとしてアクセスすることができます。

// グローバル変数であるため、プログラム内どこからでも参照できる
var global = 'global';

function scope(){
  // 関数内だが、varやconst、letなどを使用していないため、グローバル変数となる
  global2 = 'global2';
}

グローバル変数を使用する際には注意が必要で、グローバルスコープを使用するということはプログラム全体へ影響することを意味します。

バグの原因になったり、コード修正の際に影響反映が広すぎたりとコードの保守性を低下させる原因になるので、基本的にグローバル変数は使用しない方が良いです。

関数スコープ

関数スコープとは、名前の通り関数の中が有効範囲となるスコープです。

関数スコープ内でvarletconstを使用して変数宣言をすることで関数スコープが形成されます。

また、関数の仮引数も同じく関数スコープを持ち、関数の外からは参照ができません。

function func(){
  const local = 'local';
  console.log(local);
}

func();
// local

console.log(local);
// エラー (関数スコープのため、参照できない。)

ブロックスコープ

ブロックスコープとは、 ES6(ES2015)より追加されたスコープで、ブロック({ } で囲われた範囲)が有効範囲となります。

if文やfor文と一緒に使用されることが多いブロックスコープですが、意図的にブロックを生み出すこともできます。

ブロック内でlet、constを使用して変数を宣言することでブロックスコープを持つローカル変数となり、ブロックの外から参照することができなくなります。

let global = 'global';

{
  let local = 'local';
}

console.log(global);
// global
console.log(local);

// エラー (変数localはブロックスコープのため、ブロック{}の外からは参照できない)

宣言文とスコープ

変数を宣言する際に使用するvarやlet、constは、使用する宣言文に応じてスコープを生成します。

ブロックスコープ関数スコープ
var×
let
const

let、const

ES6(ES2015)より追加されたlet、constを使用して宣言した変数は、ブロックスコープと関数スコープの両方を生成します。

ES6(ES2015)以降、varを使う必要がなくなり、基本的にletかconstを使用して変数を宣言するようになりました。

JavaScriptの「let」「const」「var」の違いと使い分け

var

varを使用して宣言した変数は、関数スコープのみを生成します。

そのため、varを使用して宣言した変数は、ブロック{}の外からでも参照することができます。

{
  var funcScope = 'SCOPE';
}

console.log(funcScope);
// SCOPE  (ブロックスコープを生成しないため、ブロック{}の外からでも参照できる)

まとめ

JavaScriptにおけるスコープとは、関数や変数の有効範囲であり、スコープを正しく理解し適切に使用することで保守性の高いコードをかけるようになります。

グローバル変数はプログラム内どこからでも参照でき、バグの原因にもなりかねないため基本的に使用しないようにしましょう。

スコープを意識してコーディングを行い、保守性の高いJavaScriptコードをかけるようになりましょう。

コメント

タイトルとURLをコピーしました