javascript設計モードの単一例(singleton)モード


singletonモードはクラスの実装回数を制限しています.一回しかありません.singletonモードは、このインスタンスが存在しない場合、1つの方法によってクラスを作成し、クラスを作成する新しいインスタンスを実現することができる.インスタンスが既に存在する場合、オブジェクトの参照を簡単に返します.Singletonは静的なクラスとは異なり,実用化を遅らせることができる. 
 
1.対象文字数の実現
     Javascriptでは単例モードを実現する方法がたくさんあります.その中で一番簡単なのは対象の字面量です.
var Singleton={
     name:"vuturn",
     showName:function(){
          console.log(this.name);
         }
  }
  もちろん、オブジェクトを拡張してもよく、プライベートメンバおよび方法を追加して、その内部に閉込められたパッケージ変数および方法を使用してもよい.オブジェクトを返すことによって、公有の方法と変数が露出されます.
2.クローズドで実現
  var mySingleton=(function(){
        var instance;
        function init(){
            function privateMethod(){
                console.log("This is private");
            }
            var privateVariable="This is privart too!";
            return {
             publicMethod:function(){
                 console.log("This is public!");
             },
                publicProperty:"This is public too!"
            }
        }
        return {
            getInstance: function () {
                if(!instance){
                    instance=init();
                }
                return instance;
            }
        }
    })();
3.newオペレータを使用する
私たちは以下の効果を実現します.
var uni=new Universe(),
    uni2=new Universe();
uni==uni2;

uniオブジェクトは、最初にコンストラクタを呼び出した時に作成され、2回目(または複数回以上)の時に、同じuniオブジェクトに直接戻ります.これはなぜuni==uni 2というのですか?同じ対象を指す引用です.
では、javascriptではどうやってこのモードを実現しますか? 
ユニバーサルオブジェクトにはthisオブジェクトがキャッシュされていて、2回目の呼び出し時に同じオブジェクトを作成して戻すことができます.この目標を達成するためには様々な方法があります.
(1)グローバル変数を使用して、このインスタンスを記憶することができる.しかし、大域変数がカバーされやすいので、このようなやり方は勧められません.
(2)この例は、構造関数の静的属性においてキャッシュされ得る.このような簡潔なやり方の唯一の欠点は、静的属性が公開アクセスの属性であり、外部コードが修正できることである.
(3)この例をクローズドに包装することができる.このように、インスタンスのプライベート性を保証し、インスタンスが構造関数以外のコードによって修正されないことを保証することができる.
ここでは第二と第三の実施形態を示す.
静的属性の例
 function  Universe(){
      if(typeof Universe.instance ==="object"){
          return Universe.instance;
      }
      this.start_time=0;

      Universe.instance=this;

      return this;
  }

    var uni=new Universe();
    var uni2=new Universe();

  console.log(  uni===uni2 );
クローズド中の例
 function  Universe(){
     var instance=this;

      this.start_time=0;

      Universe= function () {
          return instance;
      }
  }
    var uni=new Universe();
    var uni2=new Universe();

  console.log(  uni===uni2 );
上のコードは最初の呼び出し時に、thisポインタを返します.このときのコンストラクタは書き換えられました.後で呼び出したら、直接instanceに戻ります.このモードの欠点は,構造関数を書き換えて,初期定義と再定義の時間の間にその内部に追加されたすべての属性を失うことである.ここの特定の場合、ユニヴァースのプロトタイプに追加されたオブジェクトは、元の友達の実現に向けて作成されたアクティブリンクが存在しません.
次のテストを見てください.
    Universe.prototype.nothing=true;

    var uni=new Universe();

    Universe,prototype.everything=true;

    var uni2=new Universe();

    uni.nothing;  //true
    uni2.nothing;  //true

    uni.everything; //undefined
    uni2.everything; //undefined

    uni.constructor.name;  //Universe

    uni.constructor===Universe;  //false
uni.com nstructorがUniverse()の構造関数と同じでないのは、uni.com nstructorが元の構造関数を指しているからです.
プロトタイプとコンストラクタポインタが予想通りに運行されると、次のように実現できます.
 function  Universe(){
     var instance;

      Universe= function () {
          return instance;
      }
      //    
      Universe.prototype=this;

      instance=new Universe();
      instance.constructor=Universe;
      instance.start_time=0;

      return instance;
  }
   Universe.prototype.nothing=true;
    var uni=new Universe();
    Universe.prototype.everything=true;
    var uni2=new Universe();

    console.log(uni===uni2);
    console.log(uni);
    console.log(uni2);
    console.log(uni.constructor);