2007年11月17日土曜日

クロージャ

JavaScript のクロージャを勉強してみる。
クロージャとは以下のようなことだ。
内部関数が、外部関数が終了した後でも、常に外部関数で宣言された変数とパラメータにアクセスできること。
http://d.hatena.ne.jp/brazil/20051028/1130468761
クロージャを使わないときとクロージャを使うときを比較して考えてみる。
まずクロージャを使わないパターン。
// 引数同士を加算する関数
function adder(a, num) {
return a + num;
}

var a = adder;
var b = 3;

a(b, 2);
///// 5

a(b, 5);
///// 8
被加算数は同じなのに、毎回被加算数を書く必要があるのが少し冗長に感じる。
クロージャを使って、もう少し綺麗に書ける。
// 足し算をする関数を返す関数
function adder(num) {
return function(add){
return num + add;
};
}

var a = adder(3);

a(2);
///// 5

a(5);
////// 8
次に、以下のように、ページ訪問者にメッセージを表示する例を考えてみる。
まずはクロージャを使わずに普通に実装する。
var msg = 'welcome!';

// ロード後にメッセージを表示
window.onload = function(){
document.getElementById('msg').innerHtml = msg;
}
これだとグローバル変数がもったいない。
クロージャを使って以下のようにグローバル変数を節約できる。
// ロード後にメッセージを表示
(function(){
var msg = 'welcome!';

window.onload = function(){
document.getElementById('msg').innerHTML = msg;
})();
次はクロージャを使ってメッセージを遅延させて表示する関数を考える。
// メッセージを遅延させて表示する
function delayedMsg(msg, time) {
setTimeout(function(){
alert(msg);
}, time);
}

delayedMsg('Welcome!', 2000);
///// Welcome!
クロージャを使わない場合は、以下のようにコードが汚なくなる。
var msg = 'Welcome!';

setTimeout("alert('" + msg + "')", 2000);
///// Welcome!