1. استخدم المتغيرات العالمية لحفظ الحالات المفردة
هذه هي أسهل طريقة لتنفيذها
وظيفة person () {this.createTime = new Date () ؛ } var مثيل = new person () ؛ وظيفة getInstance () {return مثيل ؛ }عند تحميل JS هذا ، يتم إنشاء كائن الشخص وحفظه على المتغير العالمي على سبيل المثال. يؤخذ هذا الكائن في كل مرة يتم استخدامه. إذا لم تكن قد استخدمتها مرة واحدة ، فإن الكائن الذي أنشأته يضيع ، يمكننا تحسينه.
var estance function getInStance () {if (! مثيل) {مثيل = شخص جديد () ؛ } مثيل الإرجاع ؛ }بهذه الطريقة ، يتم إنشاء الكائن فقط عند استخدامه لأول مرة.
عيب هذه الطريقة هو أن مثيل هو متغير عالمي. عندما يتعاون العديد من الأشخاص أو دورة التطوير طويلة نسبيًا ، يكون من الصعب التأكد من عدم تعديل المثيل أو الكتابة فوقها بواسطة رموز أخرى. من المحتمل جدًا أنه عندما يتم استدعاء المكالمة ، يتم العثور على أن المثيل ليس كائنًا على الإطلاق.
دعونا نفكر في استخدام عمليات الإغلاق لتغليف المثيل بحيث لم يعد متغيرًا عالميًا لحل هذه المشكلة.
2. كائن خلق الإغلاق
var getInstance () {var مثيل ؛ return function () {if (! مثيل) {مثيل = شخص جديد () ؛ } مثيل الإرجاع ؛ }} () ؛وبهذه الطريقة ، يتم تغليف المثيل وليس هناك حاجة للقلق بشأن تعديله.
الآن يمكنك الحصول على Singleton من خلال وظيفة getInstance (). سؤال جديد ، إذا قمت بإنشاء كائن من خلال شخص جديد () ، ما زلت أحصل على كائنات متعددة ، ولا يمكن لـ JavaScript خصخصة المُنشئ مثل Java. فكيف يمكننا جعل الكائنات الجديدة عدة مرات مثال؟
3. مثيل ذاكرة التخزين المؤقت للسمات الثابتة
انظر إلى الكود أولاً
وظيفة person () {// إذا تم تخزين المثيل مؤقتًا ، فسيتم إرجاع المثيل المخبوق بشكل مباشر إذا (typeof person.instance === 'Object') {return person.instance ؛ } this.createTime = New Date () ؛ // in extal person.instance = this ؛ إرجاع هذا ؛ }من الكود ، يمكننا أن نرى أن المرة الأولى الجديدة ، حالة ما إذا كانت إرجاع FALSE ، ستنخفض ، وتهيئة الكائن ، ثم حفظ الكائن إلى الشخص الثابت.
في المرة الثانية الجديدة ، شرط إذا كان الإرجاع صحيحًا ، وإرجاع الشخص بشكل مباشر. لذلك بغض النظر عن عدد المرات الجديدة ، فإن الكائن الذي تم إرجاعه هو أول كائن تم إنشاؤه.
عيوب هذه الطريقة هي نفسها تلك الموجودة في الطريقة الأولى. الشخص.
دعونا نشير إلى الطريقة 2. استخدام الإغلاق لتغليف واحد قد يحل المشكلة
4. أعد كتابة المنشئ
تحتاج هذه الطريقة إلى استخدام عمليات الإغلاق ، ولكن لا يمكن أن تكون بسيطة مثل الطريقة الثانية. نحن بحاجة إلى تجاوز المُنشئ.
الدالة person () {// incaced مثيل var extry = this ؛ this.createTime = تاريخ جديد () ؛ // أعد كتابة الشخص المُنشئ = function () {return evalue ؛ }}في المرة الأولى التي يتم استدعاء جديد ، يتم تخزين المنشئ الأصلي أولاً ، ثم يتم تهيئته ، ويتم تجاوز المنشئ. عندما يكون جديدًا في المستقبل ، لن يتم استدعاء المُنشئ الأصلي أبدًا ، ولا يمكن استدعاء مُنشئ إعادة الكتابة إلا ، وهذه الوظيفة تُرجع دائمًا المثيل المخزنة مؤقتًا.
يبدو أن الطريقة أعلاه جيدة ، ولكن من خلال الاختبار التالي ، يمكنك العثور على المشكلة
// إضافة سمة person.prototype.prop1 = true ؛ var p1 = شخص جديد () ؛ // بعد إنشاء كائن التهيئة ، أضف السمة person.prototype.prop2 = true ؛ var p2 = شخص جديد () ؛ . console.log (p1.Constructor ==== person) ؛ // النتيجة هي console.log (p2.constructor === person) ؛ // النتيجة خاطئة
يجب أن تكون النتائج المتوقعة صحيحة.
تحليل رمز الاختبار أعلاه
person.prototype.prop1 = true ؛ يضيف سمة prop1 ضمن النموذج الأولي للمُنشئ الأصلي ويعين قيمة.
بعد تنفيذ var p1 = شخص جديد () ؛ ، أعيد كتابة مُنشئ الشخص
لذلك ، person.prototype.prop2 = true ؛ يضيف خاصية Prop2 تحت النموذج الأولي الجديد.
var p2 = شخص جديد () ؛ P2 و P1 هما في الواقع نفس الكائن ، أي الكائن الذي أنشأه المنشئ الأصلي
لذلك P1 و P2 لديهما Propert
وبالمثل ، يشير مُنشئ P1 و P2 أيضًا إلى المنشئ الأصلي ، ولم يعد الشخص الوظيفة الأصلية في هذا الوقت.
من أجل التشغيل كما هو متوقع ، يمكن تحقيق بعض التعديلات
الدالة person () {// incaced مثيل var extry = this ؛ // إعادة كتابة شخص مُنشئ = function () {return مثيل ؛ } // حجز نموذج السمة النموذجية. النموذج = هذا ؛ // مثيل = شخص جديد () ؛ // إعادة تعيين مثيل مرجع المنشئ. // مثيل التهيئة الأخرى. createTime = تاريخ جديد () ؛ مثيل العودة ؛ }تشغيل رمز الاختبار السابق والنتيجة صحيحة.
5. التحميل الكسول:
في المشاريع الكبيرة أو المعقدة ، يلعب دور التحسين: المكونات باهظة الثمن ولكن نادرًا ما يمكن استخدامها في المفردات المحملة كسول ، وبرامج مثال:
/ * Singleton مع أعضاء من القطاع الخاص ، الخطوة 3. */myNamespace.singleton = (function () {// أعضاء خاصين. var privateattribute1 = false ؛ var privateattribute2 = [1 ، 2 ، 3] publicmethod1: function () {...} ، publicmethod2: function (args) {...}} ؛}) () ؛/ * الهيكل العظمي العام لـ Lazy Loading Singleton ، الخطوة 1. PrivateTtribute2 = [1 ، 2 ، 3] ؛ Lazy Loading Singleton ، الخطوة 2. */mynamespace.singleton = (function () {function constructor () {// كل من رمز singleton العادي يذهب هنا ...} return {getInstance: function () {// conduct code goes.}}}) () ؛ (function () {var requiredInstance ؛ // سمة خاصة تحمل مثيلًا واحدًا. منشئ الوظائف () {// كل من رمز singleton العادي يذهب هنا ...} return {getInstance: function () {if (! ifereinstance) {// instantiene on {extreustance refereinstance = equientor () ؛}}}}}}}}6. استخدم فرع Singleton:
يمكن لف الرمز لبيئة محددة إلى مفردة متفرعة ، برنامج عينة:
/ * simplexhrfactory singleton ، الخطوة 1. */var simplexhrfactory = (function () {// الفروع الثلاثة ActiveXObject ('msxml2.xmlhtp') ؛ Var Standard = {createxhrobject: ActiveXObject('Microsoft.XMLHTTP'); } }; // To assign the branch, try each method; return whatever doesn't fail. var testObject; try { testObject = standard.createXhrObject(); return standard; // Return this if no error was thrown. } catch(e) { try { testObject = activeXNew.createXhrObject(); return activeXNew; // Return إذا لم يتم إلقاء خطأ.