PICK UP
お知らせ
JavaScript
プログラミング
JavaScriptのスコープまとめ!【global・functional・block】

JavaScriptの「スコープ」について
はじめまして、かずん(@kazoonLab)と申します。
私の担当する記事では、主にJavaScript(JS)まわりの技術や、各種ツールの紹介をしていく予定です。プロフィールはこちらに載っているので、そちらをご覧ください
本日は、JavaScriptの基本、「スコープ」について紹介していきます!
スコープとは
JavaScriptのスコープ(scope)とは、「ある変数や関数の引数を参照・更新できる範囲を示したもの」です。
スコープ内で定義された変数はスコープの中でのみ参照することができます。逆に言えば、スコープの外では参照することはできません。
JSには様々なスコープがあります。まずは、一番大きな「グローバルスコープ」の例を見てみましょう。
グローバルスコープ(global scope)
// グローバルな変数を定義
var global = 'global';
// グローバルな関数を定義
function globalFunc () {
console.log('This var is ' + global);
};
// 関数を呼び出す
globalFunc(); // --> This var is global
// 変数を更新し、関数を呼び出す
global = 'grobal2';
globalFunc(); // --> This var is global2
グローバルな変数は、プログラムのあらゆる場所から値を参照・更新できます。
一見よさげに見えますが、意図せず値を書き換えてしまったりする恐れがあります。
変数がどこまで有効であるかをハッキリさせるため、JSには「関数スコープ」というものがあります。
サンプルソースを見てみましょう。
関数スコープ(functional scope)
// グローバルな関数を定義
function globalFunc () {
// 関数内でローカルな変数を定義
var local = 'local';
// 関数内でローカルな関数を定義
function localFunc () {
console.log('This var is ' + local);
}
// ローカルな関数を呼び出す
localFunc();
};
// グローバルな関数を呼び出すと、ローカル関数が呼び出される
globalFunc(); // --> This var is local
// グローバル関数を経ず直接ローカル変数・ローカル関数を参照・実行することはできない
console.log(local); // --> undefined
localFunc(); // --> undefined
// ローカル変数と同じ名前で変数を定義しても、ローカル変数には影響はない
var local = 'not local';
console.log('This var is ' + local); // --> This var is not local
globalFunc(); // --> This var is local
関数スコープを用いると、影響範囲を関数の中だけに限定した変数・関数を定義できます。
関数の外で値が更新されることはないため、プログラムの保守性がぐんとあがります。
大事なこととして、変数を宣言する際、必ず「var」をつけてください。こちらは、後ほど出てくるlet, constと合わせ、次回の記事で紹介したいと思います。
最後に、関数スコープと似て非なる「ブロックスコープ」を紹介します。
ブロックスコープ(block scope)
ブロックスコープとは、{}
を書く文で作られるスコープを指します。
具体的には、if, else, for, while, switch, try, catch, … などです。
例を見てみましょう。
// グローバルな関数を定義
function block() {
// var を用いてローカル変数を宣言
var localVar = 'localVar';
// let を用いてローカル変数を宣言
let localLet = 'localLet';
if(true) {
// ブロック(if文)の中でローカル変数を上書き
var localVar = 'localVar2';
let localLet = 'localLet2';
console.log('if文の中ののlocalVarは' + localVar); // --> if文の中ののlocalVarはlocalVar2
console.log('if文の中ののlocalLetは' + localLet); // --> if文の中ののlocalLetはlocalLet2
}
// ブロックを通った後、localVarは更新されているのに対し、
// localLetは最初に宣言したままの値が入っている
console.log('if文を抜けた後のlocalVarは' + localVar); // --> if文を抜けた後のlocalVarはlocalVar2
console.log('if文を抜けた後のlocalLetは' + localLet); // --> if文を抜けた後のlocalLetはlocalLet
}
block();
ブロックスコープを用いることで、ブロックの中でのみ参照できる変数を作ることができます。
関数スコープよりさらに小さい感じがしますね。
なお、ブロックスコープを作る際は、変数をlet、もしくはconstで宣言する必要があります。
let、constの説明は、次回の記事でより詳細にしたいと思います。
まとめ
様々なスコープを見てきましたが、より影響範囲の小さい(バグの出にくい)変数を作るため、なるべくブロックスコープを使えると良いかと思います。
当然、関数全体で使用するなら関数スコープを使わなければなりませんし、windowオブジェクトのようにそもそもグローバルな変数なものもあります。
「この変数はここでしか使わない」という小さな判断の積み重ねが、可読性の高い、整然としたソースコードにつながっていくことでしょう。
次回の記事では、接頭辞(var / let / const)の性質についてとことん語ります!
最後までご覧いただきありがとうございます。
この記事がいいなっと思ったら読者登録をお願いいたします♪