ホーム < ゲームつくろー! < IKD備忘録

JavaScript(WSH)
スクリプト内関数とクロージャ


 JavaScript内には関数を定義することができます。例えばこんな感じです:

var res = add(100, 200);
WScript.Echo(res);

// 足し算関数
function add(a, b) {
    return a + b;
}

これはadd関数を定義しているコードです。関数は「function」を付けると定義できます。JavaScriptは型無し言語なので戻り値とか引数の型はありません。C言語を知っている人には気持ち悪いのですが、こんなもんです。

 ・・・以上(^-^;。あ、いやいや、もう少し別の話も。


@ 関数内関数

 関数の中に関数を設けることもできます:

main();

function main() {
    function add(a, b) { return a + b; }
    function sub(a, b) { return a - b; }
    function mult(a, b) { return a * b; }
    function dev(a, b) { return a / b; }

    var res = add(10, 20) + sub(20, 30) + mult(5, 6) + dev(30, 5);
    WScript.Echo(res);
}

こういうのはその関数の中だけで多用するような関数を定義する時に便利で「クロージャー(closure:閉包)」と呼ばれています。クロージャーは関数内で定義されている変数を参照できます:

main();

function main() {
    var ofs = 10;
    function offset(a) {
       return a + ofs;
    }
 
    var res = offset(40);
    WScript.Echo(res);
}

外側の関数内で定義されているofs変数をクロージャーであるoffset内で使っています。クロージャーがどのように便利なのかはWikipediaで確認してみてください。



A 関数の引数に関数

 クロージャーは関数の引数になれます。C言語の関数ポインタのようなもので、関数内の振る舞いを変えることができるので非常に便利です:

main();

function main() {
    function goodMorning(tm) {
        return "Good Morning ! Now " + tm + "o'clock";
    }
    function goodEvening(tm) {
        return "Good Evening ! Now " + tm + " o'clock";
    }
    function greeting(func, tm) {
        WScript.Echo("This is Marupeke ! " + func(tm));
    }

    // 挨拶してみよう
    greeting(goodEvening, 19);
}

goodMorning関数とgoodEvening関数は引数に時間を取り、内部でそれぞれの文字列を作って返す関数です。greeting関数はその関数と時間を引数に取って、内部でそれらを利用した文字列を作っています。greeting関数の引数に与えられた挨拶関数の振る舞いによって返す文字列が変わりますよね。