FJCT_ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

JavaScriptの基本(その3)「変数のスコープ」

JavaScriptはプログラマーの人気1位の言語と言われています。ブラウザで唯一動作が保証されているプログラミング言語ですし、サーバーサイドではNode.jsとして動作します。さまざまな分野で使われているプログラミング言語、それがJavaScriptです。

1つのプログラミングを習得すれば、他のプログラミング言語の学習も容易になります。まずJavaScriptをしっかりと学んでみましょう。

この記事ではそんなJavaScriptを学ぶ上で良くある疑問を、なるべく分かりやすく解説します。今回は「変数のスコープ」について解説します。

スコープとは

変数のスコープとは、有効範囲のことです。たとえば、以下の内容で a.js というファイルを作成します。

const a = 1;

そして、このファイルを index.html 内で読み込みます。

<script src="a.js"></script>

さらに b.js というファイルを以下の内容で作成し、HTMLで読み込みます。

console.log(a);

HTMLでの読み込みは、a.jsの後で行います。

<script src="a.js"></script>
<script src="b.js"></script>

これを実行すると、コンソールに 1 と出力されるでしょう。つまり a.js の内容が、 b.js に反映されているということです。

JavaScriptのスコープ

つまり、JavaScript(ブラウザ)のスコープは基本的にグローバルで、他のファイルを含めて全体に影響します。ただし、JavaScriptのファイルは直列で読み込まれるので、 a.js と b.js を逆に読み込むとエラーになります。

<script src="b.js"></script> <!-- ReferenceError: a is not defined -->
<script src="a.js"></script>

読み込む順番によって、エラーになることがあるので注意が必要です。

変数は基本的にグローバル

前述の通り、ブラウザ向けのJavaScriptでは変数のスコープがグローバルです。そのため、 c.js を作成して以下のような内容になっていると、エラーになります。

const a = 2;

HTMLでは以下のように読み込みます。

<script src="a.js"></script>
<script src="b.js"></script>
<script src="c.js"></script> <!-- Identifier 'a' has already been declared -->

他の人が定義した変数によって、自由に変数が定義できなくなってしまうのは困ります。そこで、各ファイルでスコープを狭めてあげるのがお勧めです。

変数のスコープを区切る

変数のスコープを各ファイルごとに区切る場合、2つの方法があります。

関数によるスコープ

まず一つ目は関数を使う方法です。ファイルの内容全体を関数で囲み、その関数を実行します。

function a_js() {
    const a = 1;
}

a_js();

この場合、関数名がグローバルスコープになってしまうので(かつ上書きできてしまう)、無名関数を即時実行するのが一般的です。

(function () {
    const a = 1;
})();

// またはアロー関数
(() => {
    const a = 1;
})();

このように関数で囲むことで、変数のスコープをファイル内に限定できます。

波括弧を使う

もっと簡単なのは波括弧を使う方法です。

{
    const a = 1;
}

以下のコードはエラーになりません。

const a = 1;
{
    const a = 2;
  console.log(a); // 2
}

変数の内容は以下のようになります。これでスコープ(変数の適用範囲)が分かるのではないでしょか。

const a = 1;
console.log(a); // 1
{
    const a = 2;
  console.log(a); // 2
}
console.log(a); // 1

逆に、以下のコードはエラーになります。波括弧内で定義されている a の前に変数を使おうとしているからです。

const a = 1;
{
    console.log(a); // ReferenceError: Cannot access 'a' before initialization
    const a = 2;
};

以下はエラーになりません。波括弧内で a を定義していないからです。

const a = 1;
{
    console.log(a); // 1
};

変数を外部に公開する

スコープを絞るのではなく、逆に公開したい場合もあるでしょう。その場合にはウィンドウオブジェクトに紐付けます。

(() => {
    window.b = 1; // 外部に公開
})();

window.b のように変数を定義すれば、他のファイルでも window.b や単に b でアクセスできます。

Node.jsの場合は異なります

今回の話はブラウザ向けのJavaScriptになります。Node.jsの場合は requireimport を使って外部ファイルの内容を読み込んだり、 export を使って外部に公開します。

まとめ

変数のスコープを知ることで、思わぬ変数定義でエラーが出たり、逆に変数が存在しないといったエラーを防げるようになります。開発時に注意してください。

ニフクラ mobile backendではJavaScript向けにSDKを提供しています。ぜひJavaScriptを使ったアプリ開発時に役立ててください。

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。