1. Gunakan variabel global untuk menghemat kasus tunggal
Ini adalah cara termudah untuk mengimplementasikannya
function person () {this.createTime = new date (); } var instance = orang baru (); fungsi getInstance () {instance return; }Saat memuat JS ini, objek orang dibuat dan disimpan ke variabel global instance. Objek ini diambil setiap kali digunakan. Jika Anda belum menggunakannya sekali, objek yang Anda buat terbuang sia -sia, kami dapat mengoptimalkannya.
var fungsi instance getInstance () {if (! instance) {instance = new person (); } return instance; }Dengan cara ini, objek dibuat hanya saat digunakan untuk pertama kalinya.
Kerugian dari metode ini adalah instance itu adalah variabel global. Ketika banyak orang bekerja sama atau siklus pengembangan relatif panjang, sulit untuk memastikan bahwa instance tidak akan dimodifikasi atau ditimpa oleh kode lain. Sangat mungkin bahwa ketika panggilan dipanggil, ditemukan bahwa instance bukan objek orang sama sekali.
Mari kita pertimbangkan untuk menggunakan penutupan untuk merangkum instance sehingga bukan lagi variabel global untuk menyelesaikan masalah ini.
2. Objek Pembuatan Penutupan
var getInstance () {var instance; return function () {if (! instance) {instance = new orang (); } return instance; }} ();Dengan cara ini, contoh dienkapsulasi dan tidak perlu khawatir tentang dimodifikasi.
Sekarang Anda bisa mendapatkan singleton melalui fungsi getInstance (). Pertanyaan baru, jika saya membuat objek melalui orang baru (), saya masih mendapatkan banyak objek, dan JavaScript tidak dapat memprivatisasi konstruktor seperti Java. Jadi bagaimana kita bisa membuat objek yang baru beberapa kali menjadi contoh?
3. Contoh cache atribut statis konstruktor
Lihat kode terlebih dahulu
function person () {// Jika instance telah di -cache, itu akan secara langsung mengembalikan instance yang di -cache jika (typeof person.instance === 'objek') {return person.instance; } this.createTime = new date (); // Cached Instance Person.Instance = this; kembalikan ini; }Dari kode, kita dapat melihat bahwa pertama kali baru, kondisi jika mengembalikan false, akan turun, menginisialisasi objek, dan kemudian menyimpan objek ke orang properti statis. Instance.
Kali kedua baru, kondisi jika mengembalikan true, langsung mengembalikan orang. Jadi tidak peduli berapa kali baru, objek yang dikembalikan adalah objek yang dibuat pertama.
Kerugian dari metode ini sama dengan metode satu. Orang. Instance juga merupakan properti publik dan dapat dimodifikasi.
Mari kita merujuk ke metode 2. Menggunakan penutupan untuk merangkum seseorang dapat menyelesaikan masalah
4. Tulis ulang konstruktor
Metode ini perlu menggunakan penutupan, tetapi tidak bisa sesederhana metode dua. Kita perlu mengesampingkan konstruktor.
function person () {// Cached instance var instance = this; this.createTime = new Date (); // Tulis ulang konstruktor person = function () {return instance; }}Pertama kali baru disebut, konstruktor asli di -cache terlebih dahulu, dan kemudian diinisialisasi, dan konstruktor ditimpa. Ketika baru di masa depan, konstruktor asli tidak akan pernah dipanggil, dan konstruktor menulis ulang hanya dapat dipanggil, dan fungsi ini selalu mengembalikan instance yang di -cache.
Metode di atas tampaknya baik -baik saja, tetapi melalui tes berikut, Anda dapat menemukan masalahnya
// tambahkan atribut orang.prototype.prop1 = true; var p1 = orang baru (); // Setelah membuat objek inisialisasi, tambahkan attribute person.prototype.prop2 = true; var p2 = orang baru (); // Mulai uji konsol.log (p1.prop1); // Hasilnya benar -benar konsol.log (p2.prop1); // hasilnya adalah konsol sejati. console.log (p1.constructor === orang); // hasilnya adalah false console.log (p2.constructor === orang); // hasilnya salah
Hasil yang diharapkan harus benar.
Menganalisis kode uji di atas
Orang.prototype.prop1 = true; Menambahkan atribut Prop1 di bawah prototipe konstruktor asli dan memberikan nilai.
Setelah mengeksekusi var p1 = orang baru ();, konstruktor orang telah ditulis ulang
Oleh karena itu, person.prototype.prop2 = true; Menambahkan properti Prop2 di bawah prototipe baru.
var p2 = orang baru (); P2 dan P1 sebenarnya adalah objek yang sama, yaitu objek yang dibuat oleh konstruktor asli
Jadi P1 dan P2 memiliki properti prop1, tetapi tidak ada properti prop2
Demikian pula, konstruktor P1 dan P2 juga menunjuk pada konstruktor asli, dan orang tidak lagi menjadi fungsi asli saat ini.
Untuk menjalankan seperti yang diharapkan, beberapa modifikasi dapat dicapai
function person () {// Cached instance var instance = this; // tulis ulang konstruktor person = function () {return instance; } // Cadangan atribut prototipe person.prototype = this; // instance = orang baru (); // Setel ulang instance referensi konstruktor.constructor = orang; // inisialisasi lain instance.createTime = tanggal baru (); instance return; }Jalankan kode uji sebelumnya dan hasilnya benar.
5. Pemuatan malas:
Dalam proyek besar atau kompleks, ia memainkan peran optimasi: komponen yang mahal tetapi jarang digunakan dapat dibungkus menjadi singleton pemuatan malas, contoh program:
/ * Singleton dengan anggota pribadi, langkah 3. */Mynamespace.singleton = (function () {// anggota pribadi. Var privateattribute1 = false; var privateAttribute2 = [1, 2, 3]; function privateMethod1 () {...} function privateMethod2 (args) {...} return {} {(... {{} public. publicMethod1: function () {...}, publicmethod2: function (args) {...}};}) ();/ * kerangka umum untuk singleton pemuatan malas, langkah 1. */Mynamespace.singleton = (function () {function constructor () {// Semua kode singleton normal. PrivateAttribute2 = [1, 2, 3]; Lazy Loading Singleton, Langkah 2. */MyNamespace.singleton = (function () {function constructor () {// Semua kode singleton normal ada di sini. ...} return {getInstance: function () {// Kode kontrol di sini.}}) () ();/ *rangka umum untuk loading loading singling singling. {Var UniqueInstance;6. Gunakan Cabang Singleton:
Kode untuk lingkungan tertentu dapat dibungkus menjadi singleton bercabang, program sampel:
/* SimpleXhrFactory singleton, step 1. */var SimpleXhrFactory = (function() { // The three branches. var standard = { createXhrObject: function() { return new XMLHttpRequest(); } }; var activeXNew = { createXhrObject: function() { return new ActivexObject ('msxml2.xmlhttp'); var standard = {createxhrobject: function () {return new xmlHttprequest ()}}}; 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 ini tidak ada kesalahan yang dilemparkan.