Jika Anda benar -benar tidak dapat memahami beberapa pengetahuan pada waktu itu, Anda dapat membiarkannya berjalan dan meninggalkannya ke masa depan dan mungkin Anda bisa memahaminya.
Beberapa bulan yang lalu, saya memegang "JavaScript Advanced Programming (Edisi Ketiga)" dan setelah mengunyah membuat objek, saya mulai mengunyah warisan. Namun, setelah mengunyah rantai prototipe, saya benar -benar tidak tahan lagi, dan pikiran saya menjadi semakin berantakan, jadi saya membuangnya dan terus melihat yang terakhir. Sekarang saya telah menggunakan liburan musim panas ini untuk memahami warisan ini, saya akan memilah catatan saya.
Rantai prototipe
Mari Baca Artikel Dulu. Penulis artikel ini sangat bagus dan dilengkapi dengan gambar definisi tinggi. tertawa terbahak-bahak…
Tautan: [Catatan Studi] Lihat rantai prototipe JS dari perspektif kecil
Beberapa kata dari teks asli
Tentukan hubungan antara prototipe dan instance
Ada dua cara untuk mendeteksi hubungan antara prototipe dan contoh:
Instanceof: Menentukan apakah objek adalah instance dari objek lain
Mekanisme komputasi internal dari instanceof adalah sebagai berikut:
functionInstance_of (l, r) {// l mewakili ekspresi kiri, r mewakili ekspresi kanan varo = r.prototype; // ambil prototipe tampilan r l = l .__ proto__; // Ambil prototipe implisit l while (true) {if (l === null) returnFalse; if (o === l) // Di sini intinya: ketika O sama dengan L, kembalikan truereturntrue; L = l .__ proto__; }}Kode di atas dikutip dari: analisis mendalam dari instance JavaScript dari operator
isPrototypeOf (): menguji apakah ada objek pada rantai prototipe objek lain
Silakan merujuk perbedaan antara kedua metode ini: JavaScript isPrototypeof vs instance dari penggunaan
Hanya menggunakan rantai prototipe untuk mencapai warisan
Kerugian: 1. Atribut prototipe yang mengacu pada nilai tipe akan dibagikan oleh instance; 2. Saat membuat instance subtipe, parameter tidak dapat diteruskan ke konstruktor supertype.
functionFather () {this.name = "ayah"; this.friends = ['aaa', 'bbb'];} functionson () {} son.prototype = newFather (); son.prototype.constructor = son; vars1 = newson (); vars2 = newson (); console.no.no.n.n.no.n.no. fadyconsole.log (s2.name); // ayah1.name = "son"; console.log (s1.name); // sonconsole.log (s2.name); // fadyconsole.log (s1.friends); // ["aaa", "bbb"] console.log. "BBB"] s1.friends.push ('ccc', 'ddd'); console.log (s1.friends); // ["aaa", "bbb", "ccc", "ddd"] console.log (s2.friends); // ["aaa", "bbb", "ccc", ""Hanya menggunakan konstruktor untuk mencapai warisan
Metode Implementasi: Hubungi Konstruktor SuperType di dalam konstruktor subtipe (menggunakan metode Apply () dan Call ())
Keuntungan: Selesaikan masalah referensi atribut tipe dalam prototipe, dan subkelas dapat meneruskan parameter ke superclass
Kerugian: Subkelas instance tidak dapat mengakses metode yang ditentukan dalam prototipe kelas induk (superclass), sehingga tidak ada cara untuk berbicara tentang fungsi kembali.
functionFather (name, friends) {this.name = name; this.friends = friends;} ayah.prototype.getname = function () {returnThis.name;}; Functionson (name) {// Catatan: Untuk memastikan bahwa konstruktor ayah tidak menimpa properti dari son constructor, tempatkan kode yang disebut bapak bapak. Ayah. son2s1.friends.push ('ccc', 'ddd'); console.log (s1.friends); // ["aaa", "bbb", "ccc", "ddd"] console.log (s2. friends); // ["aaa", "bbb"] // subklaps; // typeError: s1.getName bukan fungsi.getname (); // typeError: s2.getname bukan fungsiWarisan Kombinasi
Metode Implementasi: Gunakan rantai prototipe untuk mengimplementasikan pewarisan properti dan metode prototipe, dan gunakan konstruktor untuk mengimplementasikan pewarisan properti instan.
functionFather (name, friends) {this.name = name; this.friends = friends;} ayah.prototype.money = "100k $"; ayah.prototype.getName = function () {consol Ayah.call (ini, nama, ['aaa', 'bbb']); this.age = usia;} // mewarisi properti dan metode dalam prototipe kelas induk son.prototype = newFather (); son.prototype.constructor = son; son.prototype.getage = function () {console.construct = newson ('son1', 12); s1.friends.push ('ccc'); console.log (s1.friends); // ["aaa", "bbb", "ccc"] console.log (s1.money); // 100k $ s1.getname (); // son1s1.getage (); // 12vars2 = newson ('son2', 24); console.log (s2.friends); // ["aaa", "bbb"] console.log (s2.money); // 100k $ s2.getname (); // son2s2.getage (); // 24Kombinasi warisan menghindari cacat secara sepihak menggunakan rantai prototipe atau konstruktor untuk menerapkan warisan, menggabungkan keunggulan mereka, dan menjadi model warisan yang paling umum digunakan dalam javascript, tetapi juga cacat, dan cacat warisan kombinasi akan secara spesifik disebutkan nanti.
Warisan prototipe
Gagasan Implementasi: Gunakan prototipe untuk membuat objek baru berdasarkan objek yang ada, tanpa membuat tipe khusus karena ini.
Untuk mencapai hal ini, fungsi berikut (OBJ) diperkenalkan
functionObj (o) {functionf () {} f.prototype = o; returnNewf ();} varperson1 = {name: "Percy", Friends: ['aaa', 'bbb']}; varperson2 = obj (person1); person2.name = "zyj"; person.n.nfriFron.npush ('console' (person1); console. Percyconsole.log (person2.name); // zyjconsole.log (person1.friends); // ["aaa", "bbb", "ccc"] console.log (person2.friends); // ["aaa", "bbb", "ccc"] ecmript 5 normal. Dalam kasus lewat dalam parameter, metode objek.create () dan obj () berperilaku sama. varperson1 = {name: "Percy", Friends: ['aaa', 'bbb']}; varperson2 = object.create (person1); person2.name = "zyj"; person2. friends.push ('ccc'); console.log (person1.name); // percyconsole.log '); console.log (person1.name); // Percyconsole.log (orang2.name (orang. zyjconsole.log (person1.friends); // ["aaa", "bbb", "ccc"] console.log (person2.friends); // ["aaa", "bbb", "ccc"]Warisan ini dapat dipilih ketika tidak perlu memobilisasi konstruktor untuk membuatnya, tetapi hanya ingin satu objek tetap mirip dengan yang lain.
Warisan parasit
Warisan parasit adalah ide yang terkait erat dengan prototipe warisan.
Gagasan Implementasi: Buat fungsi yang hanya digunakan untuk merangkum proses pewarisan, yang secara internal meningkatkan objek dengan cara tertentu dan akhirnya mengembalikan objek.
functionObj (o) {functionf () {} f.prototype = o; returnNewF ();} functionCreatePerson (asli) {// Encapsulate Proses pewarisan varclone = obj (asli); // Buat objek clone.showsomething = function () {// peningkatan objek console.log ("hello world!"); "); }; returnClone; // return object} varperson = {name: "Percy"}; varperson1 = createPerson (orang); console.log (person1.name); // percyperson1.showsomething (); // halo dunia!Warisan kombinasi parasit
Mari kita bicara tentang kekurangan warisan kombinasi kami sebelumnya. Masalah terbesar dengan warisan kombinasi adalah bahwa apa pun situasinya, konstruktor kelas induk akan disebut dua kali: satu adalah ketika membuat prototipe subclass, dan yang lainnya adalah ketika memanggil konstruktor subclass, konstruktor kelas induk dipanggil di dalam konstruktor subkelas.
functionFather (name, friends) {this.name = name; this.friends = friends;} ayah.prototype.money = "100k $"; ayah.prototype.getName = function () {consol Ayah.Panggilan pertama membuat prototipe subkelas sebagai instance dari kelas induk, sehingga prototipe subclass memperoleh atribut instance dari kelas induk; Panggilan kedua akan menyebabkan atribut instance dari subkelas untuk juga mendapatkan atribut instance dari kelas induk; dan atribut instance dari subclass akan memblokir atribut yang digandakan dengan prototipe subclass secara default. Oleh karena itu, setelah dua panggilan ini, atribut yang tidak perlu muncul dalam prototipe subclass, sehingga memperkenalkan pewarisan kombinasi parasit untuk menyelesaikan masalah ini.
Gagasan di balik pewarisan kombinasi parasit adalah: tidak perlu memanggil konstruktor kelas induk untuk menentukan prototipe subclass. Yang kami butuhkan hanyalah salinan prototipe kelas induk.
Pada dasarnya, ini adalah menggunakan pewarisan parasit untuk mewarisi prototipe kelas induk, dan kemudian mengembalikan hasilnya ke prototipe kelas anak.
functionObj (o) {functionf () {} f.prototype = o; returnNewf ();} functioninHeritePrototype (son, ayah) {varprototype = obj (bapak.prototype); // buat objek prototype.constructor = son; // Tingkatkan objek son.prototype = prototipe; // Return Object} functionFather (name, friends) {this.name = name; this.friends = friends;} ayah.prototype.money = "100k $"; Father.prototype.getname = function () {console.log (this.name);}; functionson (nama, usia) {// propert Ayah.call (ini, nama, ['aaa', 'bbb']); this.age = usia;} // mewarisi properti dan metode dalam kelas induk prototipe prototipe prototipe (son, ayah); son.prototype.getage = function () {console.log (this.age);}; vars1 = newson ('son1', 12); s1.friends.push ('ccc'); console; console. "bbb", "ccc"] console.log (s1.money); // 100k $ s1.getname (); // son1s1.getage (); // 12vars2 = newson ('son2', 24); console.log (s2.friends); // ["aaa", "bbb"] console.log (s2.money); // 100k $ s2.getname (); // son2s2.getage (); // 24Keuntungan: Buat prototipe subkelas hindari mewarisi sifat instance yang tidak perlu di kelas induk.
Pengembang umumnya percaya bahwa pewarisan kombinatorial parasit adalah metode pewarisan paling ideal berdasarkan jenis pewarisan.
akhirnya
Akhirnya, saya sangat merekomendasikan dua artikel yang sangat sulit
JavaScript bagaimana warisan prototipe benar -benar berfungsi
Diagram warisan pseudo javascript (perlu melintasi dinding)
Ambil gambar yang sulit dari artikel kedua:
Setelah membacanya, saya memahami rantai prototipe dalam hitungan detik. Apakah ada sesuatu?
Di atas adalah kumpulan informasi yang diwarisi oleh JavaScript. Kami akan terus menambahkan informasi yang relevan di masa mendatang. Terima kasih atas dukungan Anda untuk situs web ini!