my story blog

JavaScriptとかRubyの技術的なことを書きたい

JavaScriptでSingletonパターン

御存知の通りJavaScriptにはクラスの概念がないので 実装方法はいくつかあるみたい。

オブジェクトリテラルを使ったパターン

シンプルだけど全部パブリックっすね。

var setting = {
  speed: 100,
  doubleSpeed: function () {
    return this.speed * 2;
  }
}

console.log(setting.speed); //100
console.log(setting.doubleSpeed()); //200
var singleA = setting;
var singleB = setting;
console.log(singleA === singleB); // true

 

クロージャを利用した場合

var setting = (function () {
  return {
    speed: 100,
    doubleSpeed: function () {
      return this.speed * 2;
    }
  }
}());

console.log(setting.speed); //100
console.log(setting.doubleSpeed()); //200
var singleA = setting;
var singleB = setting;
console.log(singleA === singleB); // true
privateな値を利用する場合
var setting = (function () {
  var _speed = 100; //readonly
  return {
    doubleSpeed: function () {
      return _speed * 2;
    },
    getSpeed: function () {
      return _speed;
    }
  }
}());
console.log(setting._speed); //undefined
console.log(setting.doubleSpeed()); //200

コンストラクタを利用した場合

コンストラクタで自身のインスタンスをチェックする。 この場合newを行なっても同じものが帰るようになる。

var setting;
(function () {
  var instance;

  setting = function () {
    if (instance) {
      return instance;
    }
    instance = this;

    this.speed = 100;
    this.doubleSpeed = function () {
      return speed * 2;
    };
    return instance;
  };
}());

console.log(setting().speed); //100
console.log(setting().doubleSpeed()); //200
//newしても同じ
var singleA = new setting();
var singleB = new setting();
console.log(singleA === singleB); // true

  インスタンスを判定する部分と、処理の部分を分離する場合

var setting = (function () {
  var instance;

  function init() {
    // プライベート変数、メソッド
    function halfSpeed() {
      return _speed / 2;
    }

    var _speed = 50;

    return {
      // パブリック変数、メソッド
      doubleSpeed: function () {
        return this.speed * 2
      },
      speed: 100
    };
  };

  return {
    getInstance: function () {
      //instanceがなければ生成
      if (!instance) {
        instance = init();
      }
      return instance;
    }
  };
})();
console.log(setting.getInstance().speed); //100
console.log(setting.getInstance().doubleSpeed()); //200
var singleA = setting.getInstance();
var singleB = setting.getInstance();
console.log(singleA === singleB); // true

gist: https://gist.github.com/kyohei8/5411045


参考リンク http://robdodson.me/blog/2012/08/08/javascript-design-patterns-singleton/ http://www.hardcode.nl/subcategory_1/article_526-singleton-examples-in-javascript