マルチプルインスタンスクロージャ

'use strict';
// Closureサンプルコード
// カウントアップ、ダウン、
// カウンタリセット、カウンタリードが出来るユーティリティ
// マルチプルインスタンス対応版
// 名前空間
var CounterUtil;

if (!CounterUtil) {
	// 名前空間オブジェクト生成
	CounterUtil = {};
	
	// 匿名関数即実行
	(function () {
		// コンストラクタ
		function Create() {
			// エンクロージャ定義
			this.enclosure = function () {
				var cnt = 0;		// カウンタ(クロージャ)
				
				// インスタンスフィールドにクロージャに設定
				this.reset = function () {
					return (cnt = 0);
				};
				
				this.increase = function () {
					return ++cnt;
				};
				
				this.decrease = function () {
					return --cnt;
				};
				
				this.read = function () {
					return cnt;
				};
			};
			
			// エンクロージャ実行
			this.enclosure();
		}
		
		// CounterUtilにエクスポート
		CounterUtil.Create = Create;
	})();
}

var cnt0 = new CounterUtil.Create();
var cnt1 = new CounterUtil.Create();

console.log('cnt0 r:' + cnt0.read());
console.log('cnt0 i:' + cnt0.increase());
console.log('cnt1 i:' + cnt1.increase());
console.log('cnt0 i:' + cnt0.increase());
console.log('cnt0 d:' + cnt0.decrease());
console.log('cnt1 c:' + cnt1.reset());
console.log('cnt0 d:' + cnt0.decrease());
console.log('cnt1 r:' + cnt1.read());
console.log('cnt0 i:' + cnt0.increase());
console.log('cnt0 i:' + cnt0.increase());
console.log('cnt1 i:' + cnt1.increase());
console.log('cnt0 d:' + cnt0.decrease());
console.log('cnt0 c:' + cnt0.reset());
console.log('cnt1 d:' + cnt1.decrease());

とりあえず書いてみた。ベストプラクティスかはこれから調べる。

  1. コンストラクタ内でインスタンスフィールドにエンクロージャを設定
  2. エンクロージャ内でインスタンスフィールドにクロージャを設定
  3. コンストラクタ内でエンクロージャ実行

という手順でコーディング。

欲しいのはクロージャで、エンクロージャはどうでもいいので、
エンクロージャ格納インスタンスフィールドは、実行するためだけに存在する。
匿名即実行関数で書きたかったが、普通に関数リテラルで書くとインスタンス
として実行できない?どうなんだろう。