JavaScript:これで脱初心者!レキシカルスコープとクロージャについて

いままでなんとなく使っていた JavaScript のスコープとクロージャについて、あらためて勉強し直しました。

スコープ自体難しいものではありませんが、ここをしっかり理解してないと、クロージャについての説明が出来ないので、自分用のためにメモを残しておきたいと思います。

レキシカルスコープとクロージャについて

JavaScript では関数内で宣言された変数は、その関数内でしか見ることが出来ない。関数内に変数が見つからなかった場合、外側のスコープに変数を探しにいく。この仕組みをスコープチェーンと呼ぶ。

スコープチェーンのサンプル

function myFuncA() {
    var a = 1;
    return a;
}

function myFuncB() {
    var a = 2;
    function myFuncC() {
        var b = 3;
        return a+b;
    }
    return myFuncC();
}

console.log(myFuncA());
console.log(myFuncB());

結果

1
5

myFuncA で定義された変数 a と myFuncB で定義された変数 a は別物として扱われる。
myFuncB 内では 変数 b と 関数 myFuncC が定義され、myFuncC 内には存在しない変数 a の値を、スコープチェーンにより外側のグローバルスコープに探しにいっているため、myFuncB の結果は 5 となる。

レキシカルスコープとは

変数のスコープが関数を評価したときではなく、定義したときに決定しているという性質のスコープのことで、JavaScript ではこのレキシカルスコープが採用されている。
定義した時には既にスコープが決まっているため、静的スコープとも呼ぶ。

レキシカルスコープのサンプル

var a = 'a';
var myFunc1 = function() {
    var a = 'A';
    return function() { return a; }
}

var myFunc2 = myFunc1();

console.log(a);
console.log(myFunc2());

結果

a
A

サンプルの2つ目のログ出力は myFunc1 の返り値が関数になっているため myFunc2 ではなく myFunc2() となっている事に注意。

関数を評価したときではなく、関数を定義したときにスコープが決定されるため、myFunc2() で myFunc1 の返り値である関数 function() { return a; } のすぐ外側のスコープの変数 a = ‘A’ が代入されて評価、出力されている。

クロージャとは

「関数」と「その関数が作られた環境」という2つのものが一体となった、特殊なオブジェクトのこと。メソッドを1つだけ持つオブジェクトが必要な状況ならば、どんな時でもクロージャを使う事ができる。

実は、先ほどのサンプルの myFunc2 はクロージャになっているが、いまいちピンとこない内容なので、もっと具体的なサンプルとして、カウントアップ・ダウンするクロージャのサンプルコードを作成してみる。

クロージャのサンプル

var myCounter = function() {
    var count = 0;
    return {
        'up':function() {
            count = count + 1;
            return count;
        },
        'down':function() {
            count = count - 1;
            return count;
        }
    }
}

var mycounter = myCounter();

console.log(mycounter.up());
console.log(mycounter.up());
console.log(mycounter.up());
console.log(mycounter.down());
console.log(mycounter.down());
console.log(mycounter.down());

結果

1
2
3
2
1
0

ハッシュで up と down 関数を返すようにし、mycounter からアクセスすれば、変数の状態が保持されていることが確認出来る。

まとめ

サンプルコードを見ればやっていることは理解しているつもりでも、実際コーディングするときにパッと出てこないようでは、本当に理解しているとは言えません。

難しく考えこまず「こういうものなんだ」で片付くことも多いですが、クロージャに関しては何度も読みなおして言葉の意味を正しく理解しつつ、実際に繰り返し使用しながら理解していくしかありませんね。

この記事がみなさんのお役に立ちましたら、下記「Share it」よりブックマークやSNSで共有していただければ幸いです。

siro:chro 無料ゲーム SQN をリリースしました

img_sqn_00

sirochro 初の無料ゲームアプリ SQN をリリースしました。
記事:SQN: iOS 無料ゲームアプリ SQN - Sequential Numbers をリリース
ちょっとした時間に楽しめる完全無料のゲームなっていますので、是非ダウンロードして遊んでみてください。

↓SQN のダウンロードはこちらから

Related Contents

Pickup Contents