1. HOME
  2. ブログ
  3. エンジニアになろう!
  4. 【JavaScript】スコープを意識して保守性の高いコードを作ろう!

【JavaScript】スコープを意識して保守性の高いコードを作ろう!

JavaScriptのスコープについて

『スコープ』とは、変数や関数の有効範囲のことです。

関数や変数は、定義されたスコープ内でしか影響を与えることが出来ません。

スコープとはなぜ必要なのか、どうやって使うのかを解説します。

まずはこちらのサンプルコードをご覧ください

【実行結果】
ReferenceError: hello is not defined

上記のサンプルでは、関数 func() の中で 変数 hello を定義し、関数 func() から変数 hello を呼び出そうとしています。

実行すると ReferenceError: hello is not defined とエラーが表示されてしまいました。

「変数 hello は定義されていない」と怒られてしまいます。

次にこちらのサンプルコードをご覧ください

【実行結果】
hello world

上記のサンプルでは、関数 func() の中で、 変数 hello を定義し、関数 func() から変数 hello を呼び出そうとしています。

今回は、エラーがでることもなくメッセージを表示できました。

つまり、関数内で定義された変数は、関数内でしか実行できません。

関数内で定義された変数は、関数内でしか実行できない

関数内の変数の記憶領域は、関数が終了時に破棄されます。

そのため、一番最初で示したサンプルコードではエラーが表示されました。

異なる関数で同名のの変数やオブジェクトを定義しても、それは別物として扱われます。

ミツオカミツオカ
ちなみに、スコープを意識する必要性は?

にゃんこ師匠 にゃんこ師匠
スコープを意識する…つまりは変数や関数の有効範囲を意識すること、影響範囲を意識することだにゃ

ミツオカミツオカ
変数の影響範囲を必要最低限に抑えることで、保守性の高いプログラムになるということですね

にゃんこ師匠 にゃんこ師匠
うむ!ちなみにスコープの種類としては3つあるので覚えておくのだ
1. グローバルスコープ
2. 関数スコープ
3. ブロックスコープ ( ES2015/ES6 以降)

グローバルスコープ

グローバルスコープとは、関数の外(トップレベル)で定義した変数、関数になります。

また var をつけずに変数を定義した場合も、グローバルスコープの変数になります。

グローバル関数

グローバルスコープの変数、関数をグローバル変数、グローバル関数と言います。

グローバルスコープの変数は、プログラムのどこからでも呼び出すことができ、値を変更することもできます。

どこからでもアクセスできるため、プログラムが大きくなればなるほどに影響範囲が大きくなります。

サンプルコード

グローバル変数globalScopeを、関数globalFunc()で呼び出しています。

その後、変数の値を変更しています。

【実行結果】
this is global
this is global2

変数の中身は変更されていることが確認できます。

注意事項

グローバル変数は極力使わないようにプログラムを作成してください。

なぜならグローバル変数の値を変更した場合、プログラム全体に影響を及ぼします。

影響範囲が広いということは、なにかバグが発生しやすくなります。

また、ソースコードを改修するときに、調べなければならない範囲が広いことになり、プログラムの保守性が低下します。

関数スコープ(ローカルスコープ)

関数スコープとは、関数の中で定義した変数、関数です。

関数内の中だけその変数を利用することができます。

変数の影響範囲が関数内に限られるため、プログラム全体への影響を抑えることができます。

サンプルコード

関数 globalFunc() の中でローカル変数 localScope を呼び出しています。

また、関数globalFunc() の外から、ローカル変数 localScope を呼び出しています。

【実行結果】
This is local
ReferenceError: localScope is not defined

実行結果をみると、スコープ外からローカル変数localVal を呼び出していたためエラーがでています。

ローカル変数の影響範囲が限定的であることが確認できます。

ブロックスコープ

JavaScript の最新仕様 ES2015 (ES6) からブロックスコープの変数 let 、 const が利用可能となりました。

ブロックスコープは変数の影響範囲が、関数スコープよりも小さく、{} で囲まれた範囲になります。

そのため変数の影響範囲を for 文 や if 文の範囲で収めることができます。

:let を使った例

{}でそれぞれ変数 outBlock , inBlock を定義し、ブロックスコープの影響範囲を確認します。

【実行結果】
inside
calloutBlockVal
callinBlockVal
outside
calloutBlockVal
ReferenceError: inBlock is not defined

実行結果を見てみると、{} の内側で定義した変数は、 {} の外側で呼び出したときにエラーがでることが確認できます。

var を使った例

var で定義した変数はブロックスコープにはなりません。

そのため{}の内側で var を用いて変数を定義すると、{}の外側からでも変数にアクセスできます。

【実行結果】
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入門書はこちら!

確かな力が身につくJavaScript「超」入門

さいごに

いかがでしたでしょうか?

スコープについて理解が深まったようであれば幸いです!

こちらの記事もオススメ!


にゃんこ師匠 にゃんこ師匠
ミツオカ、今回の記事をまとめるのだ!

ミツオカミツオカ
1. JavaScript には変数の影響範囲をきめるスコープがある
2. グローバルスコープの変数、関数の影響範囲は、プログラム全体に及び、どこからでもアクセスできる
3. ローカルスコープ(関数内で定義した)変数、関数の影響範囲は、関数内に留まる
4. ブロックスコープ(let, const で定義した変数、関数)の影響範囲は、{} に囲まれた範囲に留まる
にゃんこ師匠 にゃんこ師匠
スコープを意識することで、変数の有効範囲を限定でき、バグが少なく保守性の高いコードを作成することができるのだ

ミツオカミツオカ
スコープを意識したプログラム作りの大事さが分かりました~!

書いた人はこんな人

広告メディア事業部
広告メディア事業部
「好きを仕事にするエンジニア集団」の(株)ライトコードです!

ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。

システム開発依頼・お見積もり大歓迎!

また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。

以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit

関連記事

採用情報

\ あの有名サービスに参画!? /

バックエンドエンジニア

\ クリエイティブの最前線 /

フロントエンドエンジニア

\ 世界を変える…! /

Androidエンジニア

\ みんなが使うアプリを創る /

iOSエンジニア