Jsのスコープについて

Posted by Tatsuyano on Mon, Jun 8, 2015
In
Tags js

グローバルスコープとローカルスコープしかない

Jsには2種類のスコープしかない。グローバルスコープ内で宣言した変数をグローバル変数、ローカルスコープ内で宣言した変数をローカル変数という。

  • スクリプト全体(トップレベル)で有効なグローバル変数
    • プログラム終了時までメモリを確保してしまう
    • 多用すると、名前がバッティングする可能性がある
  • 関数内でのみ有効なローカル変数
    • 関数終了時にメモリが開放される
    • 宣言時にvarをつけないと、*グローバル変数*として認識されてしまう
var hoge = 'global';  // => グローバル変数

function func () {
  var fuga = 'local'; // => ローカル変数、必ずvarをつける
  console.log(fuga);
}

また、他言語のようにブロックスコープは存在しない。
if (true) {
  var hoge = 'block';
}

console.log(hoge); // => block ブロック内で宣言した変数も参照できてしまう

## 変数の巻き上げ(hoisting) Jsには「変数の巻き上げ」という概念がある。
var hoge = 'global';

function func() {
  console.log(hoge); // => undefined なぜか global と出力されない

  var hoge = 'local';
  console.log(hoge); // => local 期待どおりの出力
}

一回目のconsole.log(hoge);で、なぜかundefinedが出力されている。これが「変数の巻き上げ」の挙動。

何が起きているかというと、Jsでは、関数内のどこで変数宣言をしても、関数の先頭で、宣言のみしたと認識されてしまうため。

つまり上記のコードは以下のように処理されている。

var hoge = 'global';

function func() {
  var hoge; // 初期値は入っていない。宣言のみ
  console.log(hoge); // => 初期値が入っていないので、undefined

  hoge = 'local';
  console.log(hoge); // => 値が入っているので、local
}

これを防ぐには、変数宣言は、*関数の先頭*で行うようにする。

まとめ

  • グローバル変数は多用しない
  • 変数宣言時は、必ず var をつける
  • ローカル変数は、関数の先頭で宣言する

参考サイト

関連記事