スコープについて

スコープとは何か

スコープ:実行中のコードから値や式が参照できる範囲
スコープの種類には
グローバルスコープ
スクリプトスコープ
関数スコープ
ブロックスコープ
モジュールスコープ
の計5種類がある

グローバルスコープ

グローバルスコープはプログラムの中でどこからでも参照することのできる変数のことを言います。
グローバルスコープはwindowオブジェクトと呼ばれるものになります。
windowオブジェクトとはjavascriptをブラウザ上で実行すると必ず生成されるオブジェクトになります。javascriptに設定されているメソッドやプロパティの親と考えてもらうといいかもしれません。
試しにコンソールに値を出力するプログラムを書いてみましょう。

let a = 100;
var b = 100;
function c() {}
debugger;  //この行に達した時点で一時停止されるようになる

このプログラムを実行したときにwindowオブジェクトが生成され、windowオブジェクトの中にaやbの変数、c()といった関数が格納されています。ですのである意味グローバルスコープはwindowオブジェクトそのものであり上記の変数と関数全部といっても過言ではないかもしれません。

スクリプトスコープ

javascriptのグローバルコンテキスト内で定義された変数のことを指します。
先ほどのコードを例に考えてみるとこのコードなのスクリプトスコープは変数aになります。
ここで変数bも定義されていますがこちらはvarで定義されておりいるためスクリプトスコープではありません。これはletやconstで定義した場合とvarで定義した場合とでは挙動が違うためです。変数varについては後ほど詳しくご説明します。

let a = 100;
var b = 100;
function c() {}
debugger;  //この行に達した時点で一時停止されるようになる

関数スコープ

関数スコープは関数を定義したときの{}で囲まれた部分が関数スコープになります。
下のコードには関数cの関数スコープの中で変数aとbは定義されています。このとき関数スコープ外で変数aを出力しようとするとエラーが出てしまします。このように関数スコープ内で定義された変数は関数スコープの中でしか使えないというふうになっています。しかしvarで定義した場合は別で関数スコープ外からでも使えます。このようにvarで定義した場合はletやconstで定義したときとは違い、スコープを無視できるという特徴があります。

let a = 100;
var b = 100;
function c() {
   let a = 100;
   let b = 100;
   console.log(a); 
   console.log(b);
}
   console.log(a); //エラーが出る
   console.log(b);
debugger;  //この行に達した時点で一時停止されるようになる

ブロックスコープ

ブロックスコープとは{ }で囲まれた部分がブロックスコープになります。ちなみに関数にも{ }はついていますが関数の場合は先に関数が定義されていますので関数スコープになります。一般的な例としてはif文などがあります。{ }内では関数スコープと同様に{ }内で定義された変数は{ }内でしか使うことはできず、varで定義された変数はブロックスコープが無視されるという特性があります。また関数もブロックスコープが無視されてしまうという特性があります。ですので基本的に変数宣言はletかconstを使う場合が多いです。

{
let a = 100;
var b = 100;
function c() {
   console.log("おはようございます");
}

console.log(a); //エラーが出る
console.log(b); //作動
c(); //作動

debugger;  //この行に達した時点で一時停止されるようになる

このようにブロックスコープ内でvarでの変数宣言や関数宣言をした場合はブロックスコープ外でも呼び出せるという変な動きを取ることがあります。変数の場合はletやconstで変数宣言すれば防げますが関数ではどうしたらいいのでしょう。次のように関数宣言を行えば防ぐことができます。

{
const c = function() {
   console.log("おはようございます");
}

c(); //エラーが出る

debugger;  //この行に達した時点で一時停止されるようになる

このように書くことによってブロックスコープ内でしか作動しなくなります。ですのでブロックスコープを使う際にはletもしくはconstで変数宣言や関数宣言をするように心がけましょう。

コメント

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