2012年11月27日火曜日

世界一簡単なJAVA Scriptのクロージャの解説

JAVA Scriptにはクロージャと呼ばれる仕組みがあります。
このクロージャの概念を、さも難しそうに書いていたり、もったいぶって書いているウェブサイトを見かけます。
それを見て、難しいことかのように錯覚してしまうのではないかと、少し心配します。
特にWikipediaは、嫌がらせのように、専門用語と難解な表現を織り交ぜています。
私は難しいことを簡単に表現するのは好きですが、簡単なことを難しく言うのは好きではありません。
JAVA Scriptのクロージャはとても簡単なことです。どうか先入観を持たないで、どうせ簡単なことだろうと思って以下の説明を見てください。

まず、以下のようなプログラムがあります。

var a = 1;
function f1()
{
    alert(a);
}

関数f1の中で、変数aの内容を画面に表示します。当然、1と表示されます。
なんの変哲もないプログラムです。
JAVA Scriptでは関数の中に関数を書けますから、以下のようにすることができます。

function f2()
{
    var a = 1;
    function f1()
    {
        alert(a);
    }
    f1();
}

関数f2を実行したとします。
画面には1が表示されます。
f2の最後の行でf1をコールしています。そのf1の中で変数aの内容を表示しています。変数aは定義されたと同時に1に設定されていて、その後、変化させていませんから、1以外に考えようがありません。

では、もう一行追加して、

function f2()
{
    var a = 1;
    function f1()
    {
        alert(a);
    }
    a = 2;  // 1行追加
    f1();
}

このようにすると、今度は2が表示されます。
関数f1の中で参照している変数aの値は、aに2を代入した後の値が使われています。

「関数の中で、その外にある変数を参照したときには、その変数に最後に入れられた値が使われます。この仕組みのことをクロージャと言います。」
ちょっと不正確かもしれませんが、最初は、これでOKです。
変数aに1を設定した後に関数f1が記述されているので、見た目では関数f1で参照している変数aには、1が入っているように思えそうですが、実行したタイミングで入っている値が使われます。
この関数f1が、関数f2の中以外から(コールバックやメソッドとして)コールされたとしても、関数f1の変数aは関数f2の変数aに最後に代入された値が使われます。

クロージャは簡単なことです。問題はそれをどう使いこなすかです。
自然に理解するには、実際に使っていくことが必要です。
AJAXやイベント処理でのコールバック関数を使うときに、ネストした関数を使う機会があります。そうした際にあなた自身が実際にプログラムを書くことで、頭の中に根付いていくと思います。

0 件のコメント: