
【JavaScript】スコープを意識して保守性の高いコードを作ろう!
2021.12.20
JavaScriptのスコープについて
『スコープ』とは、変数や関数の有効範囲のことです。
関数や変数は、定義されたスコープ内でしか影響を与えることが出来ません。
スコープとはなぜ必要なのか、どうやって使うのかを解説します。
まずはこちらのサンプルコードをご覧ください
1 2 3 4 5 | function func() { var hello = "hello world" } func() console.log(hello); // => error |
【実行結果】
ReferenceError: hello is not defined
上記のサンプルでは、関数 func() の中で 変数 hello を定義し、関数 func() 外から変数 hello を呼び出そうとしています。
実行すると ReferenceError: hello is not defined とエラーが表示されてしまいました。
「変数 hello は定義されていない」と怒られてしまいます。
次にこちらのサンプルコードをご覧ください
1 2 3 4 5 | function func() { var hello = "hello world" console.log(hello); } func() |
【実行結果】
hello world
上記のサンプルでは、関数 func() の中で、 変数 hello を定義し、関数 func() 内から変数 hello を呼び出そうとしています。
今回は、エラーがでることもなくメッセージを表示できました。
つまり、関数内で定義された変数は、関数内でしか実行できません。
関数内で定義された変数は、関数内でしか実行できない
関数内の変数の記憶領域は、関数が終了時に破棄されます。
そのため、一番最初で示したサンプルコードではエラーが表示されました。
異なる関数で同名のの変数やオブジェクトを定義しても、それは別物として扱われます。
1 2 3 4 5 6 7 8 9 10 11 12 | function func0() { var hello = "hello world" console.log(hello); } function func1() { var hello = 'HEY!' console.log(hello); } func0() // => hello world func1() // => HEY! |




1. グローバルスコープ
2. 関数スコープ
3. ブロックスコープ ( ES2015/ES6 以降)
グローバルスコープ
グローバルスコープとは、関数の外(トップレベル)で定義した変数、関数になります。
また var をつけずに変数を定義した場合も、グローバルスコープの変数になります。
グローバル関数
グローバルスコープの変数、関数をグローバル変数、グローバル関数と言います。
グローバルスコープの変数は、プログラムのどこからでも呼び出すことができ、値を変更することもできます。
どこからでもアクセスできるため、プログラムが大きくなればなるほどに影響範囲が大きくなります。
サンプルコード
1 2 3 4 5 6 7 8 9 10 11 | var globalScope = 'global'; // グローバル関数 function globalFunc() { console.log('this is ' + globalScope) } // グローバル変数、グローバル関数はどこでも呼び出せるし、変更できる。 globalFunc(); // => this is global globalScope = 'global2'; globalFunc(); // => this is global2 |
グローバル変数globalScopeを、関数globalFunc()で呼び出しています。
その後、変数の値を変更しています。
【実行結果】
this is global
this is global2
変数の中身は変更されていることが確認できます。
注意事項
グローバル変数は極力使わないようにプログラムを作成してください。
なぜならグローバル変数の値を変更した場合、プログラム全体に影響を及ぼします。
影響範囲が広いということは、なにかバグが発生しやすくなります。
また、ソースコードを改修するときに、調べなければならない範囲が広いことになり、プログラムの保守性が低下します。
関数スコープ(ローカルスコープ)
関数スコープとは、関数の中で定義した変数、関数です。
関数内の中だけその変数を利用することができます。
変数の影響範囲が関数内に限られるため、プログラム全体への影響を抑えることができます。
サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 | // グローバル関数 function globalFunc() { // ローカル変数 var localScope = "local"; console.log('This is ' + localScope); } // ローカル変数を呼びだす globalFunc(); // => This is localVal // ローカル変数をスコープ外から呼び出し。スコープ外なので利用できない console.log(localScope) // => error : undefined |
関数 globalFunc() の中でローカル変数 localScope を呼び出しています。
また、関数globalFunc() の外から、ローカル変数 localScope を呼び出しています。
【実行結果】
This is local
ReferenceError: localScope is not defined
実行結果をみると、スコープ外からローカル変数localVal を呼び出していたためエラーがでています。
ローカル変数の影響範囲が限定的であることが確認できます。
ブロックスコープ
JavaScript の最新仕様 ES2015 (ES6) からブロックスコープの変数 let 、 const が利用可能となりました。
ブロックスコープは変数の影響範囲が、関数スコープよりも小さく、{} で囲まれた範囲になります。
そのため変数の影響範囲を for 文 や if 文の範囲で収めることができます。
:let を使った例
{}の中と外でそれぞれ変数 outBlock , inBlock を定義し、ブロックスコープの影響範囲を確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function func() { let outBlock = "outBlockVal" // ブロックを宣言 { let inBlock = 'inBlockVal' // ブロック内で変数を呼び出す console.log('inside') console.log('call ' + outBlock) // => call outBlockVal console.log('call ' + inBlock) // => call inBlockVal } // ブロック外から変数を呼び出す console.log('outside') console.log('call ' + outBlock) // => call outBlockVal console.log('call ' + inBlock) // => ブロック外のため呼び出せない } func() |
【実行結果】
inside
calloutBlockVal
callinBlockVal
outside
calloutBlockVal
ReferenceError: inBlock is not defined
実行結果を見てみると、{} の内側で定義した変数は、 {} の外側で呼び出したときにエラーがでることが確認できます。
var を使った例
var で定義した変数はブロックスコープにはなりません。
そのため{}の内側で var を用いて変数を定義すると、{}の外側からでも変数にアクセスできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function func() { var outBlock = "outBlockVal" // ブロックを宣言 { var inBlock = 'inBlockVal' // ブロック内で変数を呼び出す console.log('inside') console.log('call ' + outBlock) // => call outBlockVal console.log('call ' + inBlock) // => call inBlockVal } // ブロック外から変数を呼び出す console.log('outside') console.log('call ' + outBlock) // => call outBlockVal console.log('call ' + inBlock) // => call inBlockVal } func(); |
【実行結果】
inside
calloutBlockVal
callinBlockVal
outside
calloutBlockVal
callinBlockVal
JavaScript にブロックスコープはない?
JavaScript の解説記事には「ブロックスコープがない」という記述が散見されます。
しかし、先述のように JavaScript にもブロックスコープは存在します。
ただし、ブロックスコープの仕様が定められたのが、2015年のため古いブラウザでは対応していない場合があります。
let・const のブラウザの対応状況
現在のブラウザの対応状況は以下で確認できます。
ECMAScript 6 compatibility table
現在の最新ブラウザ ( Edge, Chrome, Firefox, Safari ) は標準で対応しています。(IE 11 では一部未対応)
古いブラウザまでサポートに含める場合、Babel 等のトランスパイラを利用して、ES5 のコードに変換する方法がとられます。
オススメのJavaScript入門書はこちら!
さいごに
いかがでしたでしょうか?
スコープについて理解が深まったようであれば幸いです!
こちらの記事もオススメ!




書いた人はこんな人

- 「好きを仕事にするエンジニア集団」の(株)ライトコードです!
ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。
システム開発依頼・お見積もり大歓迎!
また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。
以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit
ITエンタメ10月 13, 2023Netflixの成功はレコメンドエンジン?
ライトコードの日常8月 30, 2023退職者の最終出社日に密着してみた!
ITエンタメ8月 3, 2023世界初の量産型ポータブルコンピュータを開発したのに倒産!?アダム・オズボーン
ITエンタメ7月 14, 2023【クリス・ワンストラス】GitHubが出来るまでとソフトウェアの未来