小池啓仁 ヒロヒト応援ブログ By はてな

小池啓仁(コイケヒロヒト)の動画など。

小池啓仁 ヒロヒト応援ブログ By はてな

JavaScriptでのクロージャについて

JavaScriptでのローカル変数のスコープは、関数単位です(Perlのようにブロック単位でない)。
つまり、関数内で定義されたローカル変数は、関数実行後は破棄されます。
しかし、そのローカル変数を内部関数で参照している場合は、破棄されないのです。
つまり、このローカル変数をメモとして継続利用ができるのです。
このような内部関数をクロージャと云います。

<script type="text/javascript">
function counter() {
    var count = 0;
    return function() {
        document.write(++count + "<br>");
    };
}
c1 = counter();
c2 = counter();
c1();  // 1
c1();  // 2
document.write("--------<br>");
c2();  // 3でなく1
c2();  // 2
</script>

関数(counter)が呼ばれる毎に、この関数のCallオブジェクトからグローバルオブジェクトへスコープチェーンができる。
つまり、呼ばれる毎にスコープチェーンができるわけです。
そして、それぞれのスコープチェーンの中にローカル変数(count)が存在するのです。
別の言い方だと、関数(counter)のリターン値が代入されたc1やc2には、無名関数の参照と一緒にcountの参照も閉じ込められるのです。たぶん。
だから、『// 3でなく1』になるのです。