1.グローバル変数を使用して、単一のケースを保存します
これは、それを実装する最も簡単な方法です
function person(){this.createtime = new date(); } var instance = new Person();関数getInstance(){return instance; }このJSをロードすると、個人オブジェクトが作成され、インスタンスグローバル変数に保存されます。このオブジェクトは、使用されるたびに撮影されます。一度使用していない場合、作成したオブジェクトは無駄になります。最適化できます。
var instance関数getInstance(){if(!instance){instance = new Person(); } returnインスタンス; }このようにして、オブジェクトは初めて使用された場合にのみ作成されます。
この方法の欠点は、インスタンスがグローバル変数であることです。複数の人が協力したり、開発サイクルが比較的長い場合、インスタンスが他のコードによって変更または上書きされないようにすることは困難です。呼び出しが呼び出されると、インスタンスがまったく人物ではないことがわかります。
閉鎖を使用してインスタンスをカプセル化することを検討して、この問題を解決するためのグローバル変数ではなくなるようにしましょう。
2。閉鎖作成オブジェクト
var getInstance(){var instance; return function(){if(!instance){instance = new Person(); } returnインスタンス; }}();このようにして、インスタンスはカプセル化されており、変更されることを心配する必要はありません。
これで、getInstance()関数を介してシングルトンを取得できます。新しい質問、新しい人()を介してオブジェクトを作成すると、まだ複数のオブジェクトを取得し、JavaScriptはJavaのようなコンストラクターを民営化できません。では、どうすれば複数回新しいオブジェクトをインスタンスにすることができますか?
3。コンストラクターの静的属性キャッシュインスタンス
最初にコードを見てください
function person(){//インスタンスがキャッシュされている場合、キャッシュされたインスタンスを直接返します。 } this.createtime = new date(); // cached instance person.instance = this;これを返します。 }コードから、初めての新しい時間、falseの条件が下落し、オブジェクトを初期化してから、staticプロパティパーソンのinstanceにオブジェクトを保存することがわかります。
2回目は、trueを返す場合の条件、instanceを直接返すと、初期化されたコードは実行されません。したがって、何回新しくても、返されたオブジェクトは最初の作成されたオブジェクトです。
この方法の欠点は、方法1の欠点と同じです。 person.instanceも公有財産であり、変更される場合があります。
方法2を参照しましょう。閉鎖を使用してカプセル化する場合は問題を解決する場合があります
4。コンストラクターを書き直します
この方法は閉鎖を使用する必要がありますが、方法2ほど簡単ではありません。コンストラクターをオーバーライドする必要があります。
function person(){// cached instance var instance = this; this.createtime = new date(); // constructor person = function(){return instance; }}初めて新しいと呼ばれると、元のコンストラクターが最初にキャッシュされ、次に初期化され、コンストラクターがオーバーライドされます。将来的に新しい場合、元のコンストラクターが呼び出されることはなく、書き換えコンストラクターは呼び出され、この関数は常にキャッシュされたインスタンスを返します。
上記の方法は問題ないようですが、次のテストを通じて問題を見つけることができます
//属性person.prototype.prop1 = trueを追加します。 var p1 = new person(); //初期化オブジェクトを作成した後、属性person.prototype.prop2 = trueを追加します。 var p2 = new person(); // test console.log(p1.prop1); //結果はtrue console.log(p2.prop1); //結果はtrue console.log(p1.prop2); //結果は未定義のconsole.log(p2.prop2); console.log(p1.constructor === person); //結果はfalse console.log(p2.constructor === person); //結果はfalseです
予想される結果は真実でなければなりません。
上記のテストコードを分析します
person.prototype.prop1 = true;元のコンストラクターのプロトタイプの下にprop1属性を追加し、値を割り当てます。
var p1 = new person();を実行した後、人のコンストラクタが書き直されました
したがって、person.prototype.prop2 = true;新しいプロトタイプの下にprop2プロパティを追加します。
var p2 = new person(); P2とP1は実際には同じオブジェクト、つまり元のコンストラクターによって作成されたオブジェクトです
したがって、P1とP2にはプロパティprop1がありますが、プロパティprop2はありません
同様に、P1とP2のコンストラクターも元のコンストラクターを指しており、現時点では人は元の機能ではなくなりました。
期待どおりに実行するために、いくつかの変更を達成できます
function person(){// cached instance var instance = this; // constructor person = function(){return instance; } //プロトタイプ属性person.prototype = thisを予約します。 // instance = new Person(); // Constructor Reference Instance.constructor = personをリセットします。 //その他の初期化instance.createtime = new date();インスタンスを返す; }以前のテストコードを実行すると、結果が当てはまります。
5。怠zyな読み込み:
大規模または複雑なプロジェクトでは、最適化の役割を果たします。高価ですが、めったに使用されないコンポーネントは、怠zyなロードシングルトン、サンプルプログラムに包むことができます。
/ *プライベートメンバーのシングルトン、ステップ3。 publicMethod1:function(){...}、publicMethod2:function(args){...}};})(); privattribute2 = [1、2、3]; function privatemethod2(... args){...} return {// publicattribute2:10、publicmethod1:function(){...怠zyなロードシングルトン、ステップ2。 (function(){var inlectinstance; //単一のインスタンスを保持するプライベート属性。function constructor(){//通常のシングルトンコードのすべてがここにあります。...} return {getInstance:function:function(){//インスタンスが存在しない場合にのみインスタンス化します。6.ブランチシングルトンを使用:
特定の環境のコードは、分岐したシングルトン、サンプルプログラムに包むことができます。
/ * Simplexhrfactory Singleton、Step 1。 }}; var activexold = {createxhobject(){'microsoft.xmlhttp'); xmlhttprequest()各方法を試してくださいActiveXold.createxhobject();