クロージャの使い道
意外にまともな説明が無いのがクロージャである。
自分も若干不安だが挑戦してみる。
クロージャと関数の違いを説明すると、少しはましになるかも。
- 関数(メソッド)の場合
var a = 0; function f(x, y) { if(a < 2) { return x + y; } else { return x * y; } } a = 1; alert(f(2, 1)); alert(f(4, 3)); a = 2; alert(f(2, 1)); alert(f(4, 3));
- クロージャの場合
function closure(a) { var clo = { f: null }; if(a < 2) { clo.f = function(x, y) { return x + y; }; } else { clo.f = function(x, y) { return x * y; }; } return clo; } var c1 = closure(1); var c2 = closure(2); alert(c1.f(2, 1)); alert(c1.f(4, 3)); alert(c2.f(2, 1)); alert(c2.f(4, 3));
関数の場合は、
そのまま呼ぶだけで、パラメータとなりうるのは、
引数、クラス変数、定数になる。
内部の処理は、静的である。
クロージャの場合は、
まず、初期化が行われる。
クロージャは初期化されてから、破棄されるまで(JavaScriptの場合は画面が切り換るまで?)、
内部に値を保持し続ける。
初期化のときに与えられたパラメータによって、内部の処理を動的に変えるというような、
ポリモーフィズム的なことも可能である。
上の例では、初期化で、関数f(x, y)の処理が定義され、内部に保持し続ける。
実際、2つのクロージャc1とc2はそれぞれが別々のオブジェクトである。
それぞれの関数f(x, y)に同じパラメータを与えても、結果は違う。
これを利用すると、c1とc2を敵と味方にして対戦させるゲームを作るとか、
クロージャ(オブジェクト)をもっと増やして太陽系シミュレーションを作ることもできる。
このようなことが、1つのクラスの中で、新たにクラスを定義しなくても可能になる。
一つのクラスの中でのみ使うオブジェクトを持ちたいとき、Javaのインナークラスと
同様な処理がシンプルな記述で実現できるのが、クロージャのメリットと言える。