じゃあこれはどうやったら使い物になるの?
同じ関数を呼ぶところまで見ると、
こんな感じで、mk_closure関数を叩くたびに新しい関数が作られる。
function mk_closure(val1,val2){
var val3 = val1 + val2;
return function(i){ val3+= i; return val3 }
}
f = mk_closure(100,5000);
kekka = f(3); // → var3 = 100+5000 なので f(3) = function(3){val3+=3;return val3}
kekka2 = f(10); // → 上のkekkaの計算でvar3=5103なので、kekka = val3 = 5103 + 10 = 5113
FF = mk_closure(20,100);
kekka3 = FF(1) // → FFは上のfとは別物なので val3 = 20 + 100 に対して、kekka = val3 = 120 + 1 = 121
ここからが本題。
mk_closure関数を叩くたびに新しい関数が作られる。
じゃあ、その新しい関数の定義を見ることはできるのか?が、前々から知りたかったのだが、今日ようやく答えを見つけた。
javascriptだと関数に対してcallerという呼出元を格納するプロパティがあるらしい。
なので
呼び出されたPrint側に自分自身のcallerを仕掛けるのがキモなのである。
function Print(val){
message = "今この関数を実行中<br>" + (Print.caller) + "<br>" + val
document.getElementById(何か適当なID).innerHTML = message;
}
function mk_closure(val1,val2){
var val3 = val1 + val2;
return function(i){ val3+= i; Print(val3); return val3 }
}
f = mk_closure(100,5000);
kekka = f(3); // → var3 = 100+5000 なので f(3) = function(3){val3+=3; Print(val3); return val3}
getElementByIDは単に出力先をDHTMLで出す場合の書き方で別にalert(message)としてもよい。
クロージャという概念を理解できたときもスゲーと思ったもんだが、動的に生成される関数の定義をさらに動的に表示できるってのにもスゲーと思った。