supermannerの落書き

基礎からおさらい。おさらいが何よりも大事なのです。ふわっとした知識、撲滅!

JSの変数スコープについて

大分お久しぶりです。

クライアントサイドを始めとして、jsの既存のコードをメンテする機会がふえてきたんですが、元のコードに「おまじない」だとか「なんかしらんけどうごく」とか書いてると、「いやいやおまじないじゃねーよ!!!理由があるんだよ!!!!!」とつっこみたくなります。

 

今回はjsのスコープについて基本的なことをおさらいがてらメモしようと思います。

まずは、よっぽどのことでも起きない限りだれでもパッと見て直感的にわかるタイプのコード 

var monster = 'poppo';

function getRareMonster() {
    var monster = 'pika';
    return monster;
}

console.log(getRareMonster());
console.log(monster);

当たり前ですが、レアモンスターをゲットする方は'pika'がはいってきます。

では次です

monster = 'poppo';

function getRareMonster() {
    console.log(monster);
    var monster = 'pika';
    return monster;
}
getRareMonster();

この位置で、monsterには一体何が入ってるでしょう。
poppo???pika????
実行してみましょう。

% node monster.js
undefined

undefinedなんです。これグローバル変数はいると思った人がなんでだろーっておもって無理やりなんかしら代入して処理進めたら大変なことになります。
というのも、javascriptの言語仕様的に、ローカル変数はスコープ内で有効となるのです。
背後でvarによって変数定義されていると、monsterは関数内ですでに「ローカル変数: monster」として有効になるのです。
そしてまだ何も代入されてないのでundefined。
ローカルスコープ内で無闇矢鱈に変数を色んな所でぼこぼこつかったりすると死んでしまうので注意が必要だった、というお話でした。
もちろん、名前がかち合ってなかったらどんどんスコープを滝登してグローバルスコープをよんでくれます。

var monster = 'poppo';

function getRareMonster() {
    console.log(monster);
    var rareMonster = 'pika';
    return monster;
}

getRareMonster();

この場合はグローバルスコープが読まれます。