Javascriptでプライベート関数
Javascriptの関数は基本すべてグローバル関数です。
場合によってはプライベート関数が必要なときもあるかと思います。
そんなときは以前紹介した名前空間とクロージャを使って実現できます。
var jp = {}; jp.dip = {}; jp.dip.emery = {}; jp.dip.emery.Counter = {}; (function() { var value = 0; //private function changeBy(val) { value += val; } //public function getValue() { return value; } //public function countUp() { return changeBy(1); } //public function countDown() { return changeBy(-1); } //public関数の設定 var ns = jp.dip.emery.Counter; ns.getValue = getValue; ns.countUp = countUp; ns.countDown = countDown; })(); : : alert(Counter.getValue()); /* 0 と表示される */ Counter.countUp(); Counter.countUp(); alert(Counter.getValue()); /* 2 と表示される */ Counter.countDown(); alert(Counter.getValue()); /* 1 と表示される */
(function() {...})();とすると無名関数がWindowのload時に実行されjp.dip.emery.Counterと関数(getValueなど)が紐づく仕組みになっています。
またローカル変数valueにも注目してください。
この変数はオブジェクト指向プログラミングでいうところのインスタンス変数のような役割をしています。
一見getValue()やcountUp()が実行されるたびに初期化されてしまいそうですが(function() {})();はload時に一度だけしか実行されないので値を保持し続けます。
また上記の例を↓のように短く書くこともできます。
var jp = {}; jp.dip = {}; jp.dip.emery = {}; jp.dip.emery.Counter = (function() { var value = 0; //private function changeBy(val) { value += val; } return { getValue: function() { return value; }, countUp: function() { return changeBy(1); }, countDown: function() { return changeBy(-1); } } })(); : : alert(Counter.getValue()); /* 0 と表示される */ Counter.countUp(); Counter.countUp(); alert(Counter.getValue()); /* 2 と表示される */ Counter.countDown(); alert(Counter.getValue()); /* 1 と表示される */
1つ目の例に比べて少し難解な気もしますが1つ目の例が理解できれば2つ目の例も理解できると思います。
こうしてみるとJavascriptってJava風の関数言語なんだなということがわかりますね。