Saat membuat objek melalui konstruktor objek atau literal objek, saat membuat banyak objek dengan antarmuka yang sama, sejumlah besar kode duplikat akan dihasilkan. Untuk kesederhanaan, model pabrik diperkenalkan.
Model pabrik
function createPerson (nama, usia, pekerjaan) {var obj = objek baru (); obj.name = nama; obj.age = usia; obj.job = pekerjaan; obj.sayhello () {alert (this.name); }; return obj;} var p1 = createPerson ("xxyh", 19, "programmer"); var p2 = createPerson ("zhangsan", 18, "mahasiswa");Cara membuat objek ini sangat menyederhanakan kode, tetapi ada juga kekurangan, yaitu, jenis objek tidak dapat ditentukan. Untuk mengatasi masalah ini, pola berikut muncul.
Mode konstruktor
Buat konstruktor khusus untuk mendefinisikan properti dan metode jenis objek khusus.
Function Person (Name, Umur, Job) {this.name = name; this.age = usia; this.job = pekerjaan; this.sayname = function () {alert (this.name); };} var p1 = orang baru ("xxyh", 19, "programmer"); var p2 = orang baru ("jack", 18, "mahasiswa");Dalam contoh di atas, orang () menggantikan createPerson (). Selain itu, ada beberapa perbedaan:
• Buat objek tanpa tampilan;
• Langsung tetapkan atribut dan metode untuk objek ini
• Tidak ada pernyataan pengembalian
Untuk membuat objek seseorang, Anda harus menggunakan operator baru. Itu dibagi menjadi 4 langkah:
• Buat objek baru
• Tetapkan ruang lingkup konstruktor ke objek baru
• Jalankan kode dalam konstruktor
• Mengembalikan objek baru
P1 dan P2 masing -masing menyimpan contoh orang.
peringatan (p1.constructor == orang); // truealert (p2.constructor == orang); // BENAR
Yang terbaik adalah menggunakan instanceof saat mendeteksi jenis:
peringatan (p1 instance dari objek); // truealert (instance P1 orang); // truealert (instance p2 objek); // truealert (instance p2 orang); // truealert (instance p2 orang); // BENAR
P1 dan P2 adalah contoh objek, karena semua objek diwarisi dari objek.
2.1 memperlakukan konstruktor sebagai fungsi
// gunakan var person = orang baru ("xxyh", 19, "programmer"); orang.sayname (); // "xxyh" // gunakan sebagai orang fungsi normal ("zhangsan", 18, "mahasiswa"); // tambahkan ke windowwindow.sayname (); // "zhangsan" // hubungi var obj dalam ruang lingkup objek lain obj = objek baru (); Person.call (obj, "jack", 29, "manager"); obj.sayname (); // "jack", OBJ memiliki semua sifat dan metode2.2 Masalah Konstruktor
Masalah dengan menggunakan konstruktor adalah bahwa setiap metode perlu diciptakan kembali pada setiap instance. P1 dan P2 keduanya memiliki metode SayName (), tetapi mereka bukan contoh fungsi. Dalam JavaScript, fungsi adalah objek, jadi setiap kali fungsi didefinisikan, suatu objek dipakai.
Konstruktor juga dapat didefinisikan seperti ini:
Function Person (Name, Umur, Job) {this.name = name; this.age = usia; this.job = pekerjaan; this.sayname = fungsi baru ("peringatan (this.name)");}Oleh karena itu, fungsi dengan nama yang sama pada contoh yang berbeda tidak sama:
alert (p1.sayname == p2.sayname); // PALSU
Namun, membuat dua fungsi dengan fungsi yang sama berlebihan, dan tidak perlu mengikat fungsi ke objek tertentu sebelum menjalankan kode.
Function Person (Name, Umur, Job) {this.name = name; this.age = usia; this.job = pekerjaan; this.sayname = SayName;} fungsi mengatakanName () {waspada (this.name);} var p1 = orang baru ("xxyh", 19, "programmer"); var p2 = orang baru ("jack", 18, "siswa");Di atas menggerakkan definisi SayName () di luar konstruktor, dan kemudian menetapkan atribut Sayname sebagai fungsi Sayname global di dalam konstruktor. Dengan cara ini, SayName berisi pointer ke fungsi, dan P1 dan P2 berbagi fungsi Sayname () yang sama yang didefinisikan dalam ruang lingkup global.
Namun, ada masalah baru dengan ini: fungsi yang ditentukan dalam ruang lingkup global hanya dapat dipanggil oleh objek tertentu. Dan jika objek mendefinisikan banyak metode, tipe referensi kehilangan enkapsulasi.
Mode rantai prototipe
Setiap fungsi memiliki properti prototipe, yang merupakan penunjuk yang menunjuk pada suatu objek. Tujuan dari objek ini adalah untuk memasukkan properti dan metode yang dapat dibagikan oleh semua contoh jenis tertentu . Prototipe adalah objek prototipe dari instance objek yang dibuat dengan memanggil konstruktor. Keuntungan menggunakan objek prototipe adalah bahwa semua instance objek dapat berbagi properti dan metode yang dikandungnya. Ini berarti bahwa alih -alih mendefinisikan informasi instance objek dalam konstruktor, informasi ini ditambahkan ke objek prototipe.
function person () {} person.prototype.name = "xxyh"; person.prototype.age = 19; person.prototype.job = "programmer"; person.prototype.sayname = function () {alert (this.name);}; var person1 = orang baru (); person1.sayname (); // "xxyh" var person2 = orang baru (); orang2.sayname (); // peringatan "xxyh" (person1.sayname == orang2.sayname); // BENAR3.1 Memahami Objek Prototipe
Cukup buat fungsi baru, properti prototipe akan dibuat untuk fungsi, yang menunjuk ke objek prototipe fungsi. Secara default, semua objek prototipe akan secara otomatis mendapatkan properti konstruktor. Properti ini berisi pointer ke fungsi di mana properti prototipe berada. Orang.prototype.constructor menunjuk ke orang.
Ketika konstruktor dipanggil untuk membuat instance, bagian dalam instance akan berisi pointer (properti internal) ke objek prototipe konstruktor, yang disebut [[prototipe]]. Diakses melalui _proto di Firefox, Safari dan Chrome. Koneksi ini ada antara instance dan objek prototipe konstruktor, bukan antara instance dan konstruktor.
Gambar berikut menunjukkan hubungan antara setiap objek:
Person.prototype menunjuk ke objek prototipe, dan points.prototype.constructor point ke orang. Selain atribut konstruktor, ada atribut tambahan lainnya dalam prototipe. Segala Sesuatu Contoh Orang Berisi Properti Internal Yang Hanya Menunjuk ke Orang. Prototipe, dan mereka tidak memiliki hubungan langsung dengan konstruktor.
Meskipun [[prototipe]] tidak dapat diakses, metode isPrototypeOf () dapat digunakan untuk menentukan apakah ada hubungan antara objek.
alert (person.prototype.isprototypeOf (person1)); // truealert (person.prototype.isprototypeof (person2)); // BENAR
Saat membaca properti objek, pencarian dilakukan, dengan tujuan atribut dengan nama yang diberikan. Pencarian dimulai dengan instance objek itu sendiri. Pencarian dimulai dari instance objek itu sendiri. Jika atribut dengan nama yang diberikan ditemukan dalam contoh, nilai atribut dikembalikan; Jika tidak ditemukan, terus cari objek prototipe yang ditunjukkan oleh pointer dan cari atribut dengan nama yang diberikan dalam objek prototipe. Jika properti ini ditemukan dalam objek prototipe, nilai properti dikembalikan.
Nilai -nilai yang disimpan dalam prototipe dapat diakses melalui instance objek, tetapi nilai yang disimpan dalam prototipe tidak dapat ditulis ulang melalui instance objek . Jika Anda menambahkan atribut ke instance dengan nama yang sama dengan atribut dalam prototipe instance, atribut akan memblokir atribut dalam prototipe.
function person () {} person.prototype.name = "xxyh"; person.prototype.age = "20"; person.prototype.job = "programmer"; orang. "oooo"; waspada (person1.name); // peringatan "oooo" (orang2.name); // "xxyh"Dalam contoh di atas, atribut nama secara pribadi1 memblokir atribut nama dalam prototipe.
Ketika atribut ditambahkan ke instance objek, atribut ini akan memblokir atribut dari nama yang sama yang disimpan dalam objek prototipe. Ini berarti bahwa keberadaan properti ini akan mencegah akses ke properti itu dalam prototipe. Gunakan Hapus untuk menghapus Properti Instance.
function person () {} person.prototype.name = "xxyh"; person.prototype.age = "20"; person.prototype.job = "programmer"; orang. "oooo"; waspada (person1.name); // peringatan "oooo" (orang2.name); // "xxyh" hapus person1.name; alert (person1.name); // "xxyh"HASOWNPROPERTY () dapat mendeteksi apakah suatu properti ada dalam sebuah instance atau dalam prototipe.
function Person() {}Person.prototype.name = "xxyh";Person.prototype.age = "20";Person.prototype.job = "programmer";Person.prototype.sayName = function () { alert(this.name);};var person1 = new Person();var person2 = new Person();alert(person1.hasOwnProperty("name")); // falseperson1.name = "oooo"; waspada (person1.hasownproperty ("name")); // BENARGambar berikut menunjukkan hubungan antara implementasi dan prototipe dalam situasi yang berbeda:
3.2 prototipe dan operator
Cara menggunakan operator: Gunakan sendiri, dalam loop for-in. Saat digunakan sendiri, operator dalam mengembalikan true ketika mengakses properti yang diberikan melalui objek , apakah itu ada dalam instance atau dalam prototipe.
function person () {} person.prototype.name = "xxyh"; person.prototype.age = "20"; person.prototype.job = "Programmer"; orang. // trueperson1.name = "ooooo"; alert ("name" in person1); // BENARDikombinasikan dengan fitur HasownProperty () sebelumnya, dapat ditentukan bahwa properti adalah properti dalam prototipe atau properti dalam contoh. Jika operator kembali mengembalikan true dan hasownproperty mengembalikan false, properti adalah properti dalam prototipe.
Function HasPrototyPePerTy (Object, Name) {return! Object.hasownProperty (name) && (name in object);}Selanjutnya, mari kita lihat penggunaan hasprototypeProperty ():
function person () {} person.prototype.name = "xxyh"; person.prototype.age = "20"; person.prototype.job = "programmer"; person.prototype.sayname = function () {waspada (this.name);}; var orang = orang baru (); warni (havePrototeP (this.name);}; var orang = new orang (); warni (havePrototeP); // truperson.name = "oooo"; waspada (hasprototypeProperty (orang, "nama")); // PALSUSaat menggunakan for-in loop, semua properti yang dapat dihitung yang dapat diakses melalui objek, termasuk properti dalam instance dan properti dalam prototipe. Atribut instance yang memblokir data yang tidak dapat dihindari dalam prototipe (mis. Atribut yang ditandai sebagai false oleh [[enumerable]]) juga akan dikembalikan dalam for-in, karena menurut peraturan, semua atribut yang ditentukan oleh pengembang dihiasi.
Untuk mendapatkan semua properti instance yang dapat dihindarkan pada suatu objek, Anda dapat menggunakan metode objek.keys ().
function person () {} person.prototype.name = "xxyh"; person.prototype.age = "20"; person.prototype.job = "programmer"; orang. // Nama, Usia, Kerja, Saynamevar P1 = Orang Baru (); p1.name = "oooo"; p1.age = 15; var p1_keys = objek.keys (p1); waspada (p1_keys); // Nama, usiaJika Anda perlu mendapatkan semua properti instan, Anda dapat menggunakan metode Object.getOwnPropertynames ()
var keys = object.getOwnPropertynames (person.prototype); alert (tombol); // "Konstruktor, Nama, Usia, Kerja, Sayname"
3.3 Sintaks prototipe yang lebih sederhana
Untuk merampingkan input, ganti objek prototipe terintegrasi dengan objek literal yang berisi semua properti dan metode.
function person () {} person.prototype = {name: "xxyh", usia: 18, job: "programmer", sayname: function () {alert (this.name); }};Di atas set person.prototype untuk sama dengan objek baru yang dibuat dalam bentuk literal objek. Hasilnya sama, tetapi atribut konstruktor tidak lagi menunjuk pada orang.
Hasil yang benar dapat dikembalikan melalui instanceof, tetapi konstruktor tidak dapat menentukan jenis objek:
var boy = orang baru (); waspada (boy instance dari objek); // truealert (instance boy orang); // truealert (boy.constructor == orang); // falsealert (boy.constructor == objek); // BENAR
Nilai konstruktor dapat diatur dengan cara berikut:
function person () {} person.prototype = {constructor: person, name: "xxyh", usia: 18, pekerjaan: "programmer", sayname: function () {alert (this.name); }};3.4 Dinamisitas rantai prototipe
Karena proses menemukan nilai dalam prototipe adalah pencarian, setiap modifikasi yang dibuat untuk objek prototipe tercermin pada instance. Tetapi jika seluruh objek prototipe ditulis ulang, hasilnya akan berbeda. Saat memanggil konstruktor, penunjuk [prototipe]] ke prototipe asli ditambahkan ke instance, dan memodifikasi prototipe ke objek lain setara dengan memotong koneksi antara konstruktor dan prototipe asli. Pointer pada instance menunjuk ke prototipe saja, bukan ke konstruktor.
function person () {} var boy = new person (); person.prototype = {constructor: person, name: "xxyh", usia: 29, pekerjaan: "programmer", sayname: function () {alert (this.name); }}; boy.sayname (); // kesalahanProses spesifiknya adalah sebagai berikut:
Seperti yang dapat dilihat dari atas, objek prototipe penulisan ulang memotong koneksi antara prototipe yang ada dan setiap contoh objek yang ada sebelumnya; Mereka merujuk pada prototipe asli.
3.5 Prototipe objek asli
Semua jenis referensi asli menentukan metode pada prototipe konstruktor. Melalui prototipe objek asli, tidak hanya metode default dapat diperoleh, tetapi metode baru juga dapat didefinisikan.
String.prototype.startswith = function (teks) {return this.indexof (teks) == 0;}; var msg = "Good Morning"; alert (msg.startswith ("bagus")); // BENAR3.6 Masalah dengan objek prototipe
Ada dua masalah dengan pola prototipe:
• Semuanya nilai atribut yang sama secara default.
• Semua atribut dalam prototipe dibagikan oleh instance
Mari kita lihat contoh di bawah ini:
function person () {} person.prototype = {konstruktor: orang, nama: "xxyh", usia: 18, pekerjaan: "programmer", teman: ["zhang san", "li si"], sayname: function () {alert (this.name); }}; var p1 = orang baru (); var p2 = orang baru (); p1.friends.push ("wang wu"); alert (p1.friends); // Zhang San, Li SI, Wang Wu Alert (P2. Friends); // Zhang San, Li Si, Wang Wu Alert (P1.Friends == P2.Friends); // BENARItem ditambahkan di atas melalui P1.Friends. Karena array teman ada secara langsung. Prototipe, itu juga tercermin dalam P2. Friends. Namun, contoh umumnya memiliki semua atribut mereka sendiri.
Gunakan mode konstruktor dan mode prototipe dalam kombinasi
Mode konstruktor digunakan untuk mendefinisikan properti instan, dan mode prototipe digunakan untuk menentukan metode dan sifat bersama. Dengan cara ini, setiap contoh akan memiliki salinannya sendiri dari atribut instance, tetapi pada saat yang sama berbagi referensi ke metode tersebut.
Function Person (Name, Umur, Job) {this.name = name; this.age = usia; this.job = pekerjaan; this.friends = ["zhang san", "li si"];} person.prototype = {constructor: person, sayname: function () {waspada (this.name); }} var p1 = orang baru ("xiao xiao yihan", 18, "programmer"); var p2 = orang baru ("Kuiba", 10, "Monster Hunt"); p1.friends.push ("Wang Wu"); waspada (P1.Friends); // Zhang San, Li SI, Wang Wu's Alert (P2. Friends); // Zhang San, Li Si Alert (P1.Friends == P2.Friends); // falsealsealert (p1.sayname == p2.sayname); // BENARDalam contoh di atas, properti instan didefinisikan dalam konstruktor, sedangkan konstruktor properti bersama dan metode SayName () didefinisikan dalam prototipe. Modifikasi P1.Friends tidak akan mempengaruhi hasil P2. Friends.
Mode prototipe dinamis
Pola prototipe dinamis merangkum semua informasi dalam konstruktor, dan dengan menginisialisasi prototipe dalam konstruktor, ia mempertahankan keuntungan menggunakan konstruktor dan prototipe. Dengan kata lain, dimungkinkan untuk menentukan apakah prototipe perlu diinisialisasi dengan memeriksa apakah suatu metode yang seharusnya ada efektif.
orang fungsi (nama, usia, pekerjaan) {// properti this.name = name; this.age = usia; this.job = pekerjaan; // Metode if (typeof this.sayName! = "Function") {person.prototype.sayname = function () {alert (this.name); }}}Ini hanya akan ditambahkan ke prototipe ketika metode SayName () tidak ada, dan hanya akan dieksekusi ketika konstruktor dipanggil untuk pertama kalinya.
Pola konstruktor parasit
Gagasan dari pola ini adalah untuk membuat fungsi yang fungsinya adalah merangkum kode yang membuat objek dan kemudian mengembalikan objek yang baru dibuat.
function person (name, use) {var obj = new objek (); obj.name = nama; obj.age = usia; obj.sayname = function () {alert (this.name); } return obj;} var boy = orang baru ("xxyh", 19, "programmer"); boy.sayname ();Perlu dicatat: Pertama -tama, objek yang dikembalikan tidak memiliki hubungan dengan konstruktor atau atribut prototipe konstruktor; Objek yang dikembalikan oleh konstruktor tidak berbeda dengan objek yang dibuat di luar konstruktor. Contoh operator tidak dapat diandalkan untuk menentukan jenis objek.
Pola konstruktor yang stabil
Objek yang aman mengacu pada objek yang tidak memiliki atribut publik dan metodenya tidak merujuk pada ini. Konstruktor yang stabil mengikuti pola yang mirip dengan konstruktor parasit, tetapi ada dua perbedaan:
• Metode instan dari objek yang baru dibuat tidak merujuk pada ini;
• Konstruktor tidak dipanggil menggunakan operator baru
Tulis ulang konstruktor orang sebagai berikut:
orang fungsi (nama, usia, pekerjaan) {var obj = objek baru (); obj.sayname = function () {alert (name); }; kembalikan obj;} orang fungsi (nama, usia, pekerjaan) {var obj = objek baru (); obj.sayname = function () {alert (name); }; kembalikan obj;}Artikel di atas secara singkat berbicara tentang pembuatan objek JavaScript adalah semua konten yang saya bagikan dengan Anda. Saya harap ini dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.