Javascriptの変数スコープについて少しだけまとめてみた

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

Javascriptのスコープについて整理していみたい。

ローカル/グローバル変数

まず、変数のスコープは大きく分けて2種類ある。
特定のスコープ内でのみ有効なローカル変数とあらゆるスコープで有効なグローバル変数。

Javascriptには関数スコープしかなく、
関数の中でvarをつけて宣言することで、その関数内でのみ参照が可能なローカル変数が宣言できる。

(function() {
var localVal = 'local';
console.log(localVal);
})();
console.log(localVal);

->local
->ReferenceError: localVal is not defined

上の例では、最初に定義されている関数内でのみ変数localValが参照可能であり、
関数外では参照不可であることが見てわかると思う。

グローバル変数を宣言するには以下の2種類の方法がある。
1. 関数外の場所で宣言する
2. varを付けずに宣言する
1はC言語なんかでもいっしょだけど、関数宣言の外の場所で変数宣言を行うと
その変数はグローバルになる。
※ブラウザ上で実行する場合はちょっと話が変わってくるかもしんないけど
2についてはvarを付けずに知らず知らずのうちに変数がグローバルになってたってことがよくあるので、気を付けたい。
たくさんのソースが混じり合うような大規模なシステムになってくるとグローバル変数はバグの原因になりやすい。

関数内ローカル変数宣言は全部先頭に移動しちゃう法則

スコープからすこし話がずれるかもですが、
JSでは”関数内ローカル変数宣言は全部先頭に移動しちゃう法則”があります。
下の例を見てください。

(function() {
console.log(v1);
// undefined
var v1 = 'hoge';
console.log(v1);
// hoge
})();

この例だと最初の出力ではv1は宣言してねーよっていうJSエラーが発生するのではなく、
あくまでつつましくundefinedという値が入っています。
これは、変数宣言はされてるけどなんも入ってねーよってことなんですね。
このことからv1が宣言されているのが最初の出力の後にも関わらず宣言されてるってことがわかると思います。
これがJSの”関数内ローカル変数宣言は全部先頭に移動しちゃう法則”です。

これだとなんだか気持ち悪いので、以下の例のように変数宣言は全部関数の最初にしちゃいましょう。

(function() {
var v1 = 'foo', v2 = 'bar', v3 = 'hoge';
console.log(v1);
console.log(v2);
console.log(v3);
})();

スコープチェイン

JSにはスコープチェインというかっこいい名前の仕組みがあって、
もし、スコープ内に変数が見つからない場合、その上階層のスコープに変数を探しに行くってのがあります。
階層っていうのは関数のネスト関係のことです。
下の例を見てもらえるとわかると思います。


// parent func
(function() { //①
var parentVal = 'parent';

// child func
(function() { //②
console.log(parentVal);
})();

})();

この例では、関数①の中で変数parentValが定義されていて、
関数②では何も変数が定義されていない。
上で述べたようにJSで変数のスコープは関数の中だけだよって言うのに従うと、
当然”定義されてねーよ”って怒られるはず。
しかし、この場合はエラーにならず関数①で定義された変数parentValが使用される。
これがスコープチェインというもので、ある関数内で変数が使用されるとき、
その変数がスコープ内に見つからない場合は、
その上階層(ネストされた上の)関数のスコープを探しに行くという仕組みが働いてるわけなんですね。
この連鎖は1度だけでなく、スコープがグローバルになるまで繰り返されて、
最終的にグローバル領域に宣言されていない場合、undefinedだと怒られます。


以上、Javascriptのスコープについて少しだけまとめてみましたが、
お役にたてましたでしょうか。
スコープチェインの辺りは少し不安でございます。

—-

Javascript初心者におすすめなのがこちらの本。
Javascriptの”良い書き方”の紹介とともに、変数スコープなどJavascript言語の詳細がわかりやすく書いてある。
初心者にはちょっと難しいところもあるが、これを読破すれば中級JSerの仲間入りだろう。

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

コメントを残す