@ledsun blog

無味の味は佳境に入らざればすなわち知れず

JavaScriptでSigletonオブジェクトを実装してみる

いろいろなSingletonを実装してみます。

関数

var getSingleton = (function() {
  var instance = null,
    init = function() {
      instance = { value: Math.random() }
    };

  return function() {
    if (instance == null) {
      init();
    }
    return instance;
  };
})();
var a = getSingleton();
var b = getSingleton();

console.log(a == b); //true
console.log(a.value == b.value); //true

var c = Object.create(a);
console.log(a == c); //false
console.log(a.value == c.value); //true

JavaScript デザインパターンの実装から関数を抜いてきただけなので同じ動きです。

Sigleton属性を継承する

var singleton = (function() {
  return {
    getObject: function() {
      if (this.instance === undefined && typeof(this.init) === 'function') {
        this.instance = this.init();
      }
      return this.instance;
    }
  };
})();

var mySingleton = Object.create(singleton, {
  init: {
    value: function() { return { value: Math.random() }; }
  }
});

var mySingleton2 = Object.create(singleton, {
  init: {
    value: function() { return { value: 1 }; }
  }
});

var a = mySingleton.getObject();
var b = mySingleton.getObject();

console.log(a === b); //true
console.log(a.value === b.value); //true

var c = Object.create(a);
console.log(a === c); //false
console.log(a.value === c.value); //true

var d = mySingleton2.getObject();
console.log(a === d); //false
console.log(a.value === d.value); //false

singletonオブジェクトを継承して、固有の初期化メソッドを拡張できます。 でも、シングルトンをたくさん作るコードは捨てた方がいいです。

継承より委譲

Rubyにはmodule Singleton があってかっこいいので 真似してみます。

var getObject = function () {
  if (this.instance === undefined) {
    this.instance = Object.create(this);
  }
  return this.instance;
}

var a = {
  value : Math.random(),
  getObject : getObject
} 

インスタンス化の統一インタフェースがないのでObject.createを使ってみました。 でも、先にaオブジェクトを作る時点で、もう一度Object.createする必要がありません。 我ながら修行の足りなさを実感、まだクラス悩から解脱できません。