Rumah  >  Artikel  >  hujung hadapan web  >  Ringkasan 9 kaedah pelaksanaan warisan dalam kemahiran JavaScript_javascript

Ringkasan 9 kaedah pelaksanaan warisan dalam kemahiran JavaScript_javascript

WBOY
WBOYasal
2016-05-16 15:58:301014semak imbas

Tidak seperti bahasa pengaturcaraan berasaskan kelas seperti C dan Java, pewarisan dalam JavaScript adalah berasaskan prototaip. Pada masa yang sama, kerana JavaScript ialah bahasa yang sangat fleksibel, terdapat banyak cara untuk melaksanakan warisan.

Konsep asas pertama ialah mengenai pembina dan rantai prototaip Pembina objek induk dipanggil Ibu Bapa, pembina objek anak dipanggil Anak, dan objek ibu bapa dan anak yang sepadan adalah ibu bapa dan anak.

Terdapat atribut tersembunyi [[prototaip]] (nota bukan prototaip) dalam Chrome ia adalah __proto__, tetapi dalam sesetengah persekitaran ia tidak boleh diakses. Apabila mengakses sifat atau kaedah mana-mana objek, semua sifat objek akan dicari terlebih dahulu Jika tidak dijumpai, sifat pada objek prototaip akan dicari langkah demi langkah di sepanjang rantai prototaip mengikut [[prototaip]] sehingga ditemui. Jika tidak, kembali tidak ditentukan.

1. Warisan rantaian prototaip:

Rantai prototaip ialah cara lalai untuk melaksanakan pewarisan dalam JavaScript Jika anda mahu objek anak mewarisi objek induk, cara paling mudah ialah menghalakan atribut prototaip pembina objek anak kepada contoh objek induk:

Salin kod Kod adalah seperti berikut:

fungsi Induk() {}
fungsi Kanak-kanak() {}
Child.prototype = Induk() baharu

Pada masa ini, atribut prototaip Kanak-kanak telah ditulis semula dan menunjuk ke objek baharu, tetapi atribut pembina objek baharu ini tidak menghala ke Child dengan betul Enjin JS tidak akan menyelesaikan kerja ini secara automatik untuk kami, yang memerlukan kami secara manual harta pembina objek prototaip Kanak-kanak menunjuk semula kepada Kanak-kanak:
Salin kod Kod adalah seperti berikut:

Child.prototype.constructor = Kanak-kanak

Di atas ialah mekanisme pewarisan lalai dalam JavaScript, yang memindahkan sifat dan kaedah yang perlu digunakan semula ke objek prototaip, dan menetapkan bahagian yang tidak boleh digunakan semula sebagai sifat objek sendiri Walau bagaimanapun, kaedah pewarisan ini memerlukan contoh baharu sebagai objek prototaip, yang cekap.

2. Warisan prototaip (rantaian bukan prototaip):

Untuk mengelakkan masalah berulang kali mencipta contoh objek prototaip dalam kaedah sebelumnya, anda boleh terus menghalakan prototaip pembina objek anak kepada prototaip pembina objek induk Dengan cara ini, semua sifat dan kaedah dalam Parent .prototaip juga boleh digunakan semula Pada masa yang sama, tidak perlu membuat contoh objek prototaip berulang kali:

Salin kod Kod adalah seperti berikut:

Child.prototype = Induk.prototaip
Child.prototype.constructor = Kanak-kanak

Tetapi kita tahu bahawa dalam JavaScript, objek wujud sebagai jenis rujukan Kaedah ini sebenarnya menunjukkan penunjuk yang disimpan dalam Child.prototype dan Parent.prototype kepada objek yang sama Oleh itu, apabila kita ingin menggunakan prototaip objek kanak-kanak Jika anda melanjutkan beberapa sifat dalam Untuk meneruskan pewarisan kemudian, prototaip objek induk juga akan ditulis semula, kerana sentiasa terdapat hanya satu contoh objek prototaip di sini, yang juga merupakan kelemahan kaedah pewarisan ini.

3. Warisan pembina sementara:

Untuk menyelesaikan masalah di atas, anda boleh menggunakan pembina sementara untuk bertindak sebagai lapisan perantaraan Semua operasi pada prototaip objek kanak-kanak diselesaikan pada contoh pembina sementara dan tidak akan menjejaskan prototaip objek induk:

Salin kod Kod adalah seperti berikut:

var F = function() {}
F.prototaip = Induk.prototaip
Child.prototype = F() baharu
Child.prototype.constructor = Kanak-kanak

Pada masa yang sama, untuk mengakses atribut dalam prototaip kelas induk dalam objek kanak-kanak, anda boleh menambah atribut yang menunjuk kepada prototaip objek induk dalam pembina objek kanak-kanak, seperti uber, dengan cara ini, objek anak boleh boleh diakses terus melalui child.constructor.uber ke objek prototaip induk.

Kita boleh merangkum kerja di atas ke dalam fungsi, dan memanggil fungsi ini pada masa hadapan boleh melaksanakan kaedah pewarisan ini dengan mudah:

Salin kod Kod adalah seperti berikut:

fungsi lanjutkan(Anak, Ibu Bapa) {
var F = function() {}
F.prototaip = Induk.prototaip
Child.prototype = F() baharu
Child.prototype.constructor = Kanak-kanak
Child.uber = Ibu bapa.prototaip
}

Kemudian anda boleh memanggilnya seperti ini:
Salin kod Kod adalah seperti berikut:

lanjutkan(Anjing, Haiwan)

4. Salinan atribut:

Kaedah warisan ini pada asasnya tidak mengubah hubungan rantaian prototaip, tetapi secara langsung menyalin semua atribut dalam objek prototaip induk kepada prototaip objek anak Sudah tentu, salinan di sini hanya digunakan untuk jenis data asas dan jenis objek hanya menyokong Pass melalui rujukan.

Salin kod Kod adalah seperti berikut:

fungsi extend2(Anak, Ibu Bapa) {
var p = Induk.prototaip
var c = Child.prototype
untuk (var i dalam p) {
         c[i] = p[i]
}
c.uber = p
}

Kaedah ini membina semula beberapa atribut prototaip, yang akan menjadi kurang cekap apabila membina objek, tetapi boleh mengurangkan carian rantai prototaip. Walau bagaimanapun, saya secara peribadi merasakan bahawa kelebihan kaedah ini tidak jelas.

5. Pewarisan antara objek:

Selain kaedah pewarisan antara pembina, anda juga boleh terus mewarisi antara objek tanpa pembina. Iaitu, salin atribut objek secara langsung, termasuk salinan cetek dan salinan dalam.

Salinan cetek:
Terima objek yang akan diwarisi, cipta objek kosong baharu pada masa yang sama, salin sifat objek yang akan diwarisi kepada objek baharu dan kembalikan objek baharu:

Salin kod Kod adalah seperti berikut:

fungsi extendCopy(p) {
var c = {}
untuk (var i dalam p) {
         c[i] = p[i]
}
c.uber = p
Kembalikan c
}

Selepas salinan selesai, atribut yang perlu ditulis semula dalam objek baharu boleh ditulis semula secara manual.

Salinan dalam:
Masalah salinan cetek juga jelas Ia tidak boleh menyalin atribut jenis objek tetapi hanya boleh lulus rujukan Untuk menyelesaikan masalah ini, salinan dalam mesti digunakan. Fokus salinan dalam terletak pada panggilan rekursif salinan Apabila sifat jenis objek dikesan, objek atau tatasusunan yang sepadan dicipta dan nilai jenis asas disalin satu demi satu.

Salin kod Kod adalah seperti berikut:

fungsi deepCopy(p, c) {
c = c || untuk (var i dalam p) {
Jika (p.hasOwnProperty(i)) {
Jika (jenis p[i] === 'objek') {
                                   c[i] = Array.isArray(p[i]) [] : {}
                 deepCopy(p[i], c[i])
              } lain {
c[i] = p[i]
            }
}
}
Kembalikan c
}

Kaedah ES5 Array.isArray() digunakan untuk menentukan sama ada parameter ialah tatasusunan yang tidak melaksanakan kaedah ini perlu merangkum shim secara manual.

Salin kod Kod adalah seperti berikut:
Array.isArray = fungsi(p) {
Kembalikan p instanceof Array
}

Walau bagaimanapun, pembolehubah tatasusunan daripada rangka kerja yang berbeza tidak boleh dinilai menggunakan pengendali instanceof, tetapi keadaan ini agak jarang berlaku.

6. Warisan prototaip:

Dengan bantuan objek induk, cipta objek baharu yang diprototaip oleh objek induk melalui pembina:


Salin kod Kod adalah seperti berikut:

Funktionsobjekt(o) {
var n
Funktion F() {}
F.prototype = o
n = neues F()
n.uber = o
Geben Sie n
zurück }

Hier wird das übergeordnete Objekt direkt als Prototyp des untergeordneten Objekts festgelegt. Die Methode Object.create() in ES5 ist diese Implementierung.

7. Gemischte Verwendung von prototypischer Vererbung und Attributkopie:

Bei der prototypischen Vererbungsmethode wird das untergeordnete Objekt auf der Grundlage des übergebenen übergeordneten Objekts erstellt. Gleichzeitig können zusätzlich zu den vom übergeordneten Objekt bereitgestellten Eigenschaften zusätzliche Objekte übergeben werden, die kopiert werden müssen:

Code kopieren Der Code lautet wie folgt:

Funktion objectPlus(o, stuff) {
var n
Funktion F() {}
F.prototype = o
n = neues F()
n.uber = o

für (var i in stuff) {
n[i] = stuff[i]
}
Geben Sie n
zurück }


8. Mehrfachvererbung:

Diese Methode beinhaltet nicht den Betrieb der Prototypenkette. Es werden mehrere Objekte übergeben, deren Attribute kopiert werden müssen, und alle Attribute werden nacheinander kopiert:

Code kopieren Der Code lautet wie folgt:

Funktion multi() {
var n = {}, stuff, i = 0,
        len = arguments.length
für (i = 0; i < len; i ) {
        stuff = arguments[i]
for (var key in stuff) {
n[i] = stuff[i]
}
}
Geben Sie n
zurück }

Die Objekte werden in der Reihenfolge kopiert, in der sie übergeben wurden. Das heißt, wenn das später übergebene Objekt dieselben Eigenschaften wie das vorherige Objekt enthält, überschreibt letzteres das erstere.

9. Konstruktorausleihe:

Die Methoden call() und apply() in JavaScript sind sehr einfach zu verwenden, und ihre Funktion, den Kontext der Methodenausführung zu ändern, kann auch eine Rolle bei der Implementierung der Vererbung spielen. Das sogenannte Konstruktor-Ausleihen bezieht sich auf das Ausleihen des Konstruktors des übergeordneten Objekts im Konstruktor des untergeordneten Objekts, um Folgendes zu betreiben:

Code kopieren Der Code lautet wie folgt:

Funktion Parent() {}
Parent.prototype.name = 'parent'

Funktion Child() {
Parent.apply(this, arguments)
}
var child = new Child()
console.log(child.name)


Der größte Vorteil dieser Methode besteht darin, dass im Konstruktor des Unterobjekts die eigenen Eigenschaften des Unterobjekts vollständig rekonstruiert werden und die Referenztypvariable auch einen neuen Wert anstelle einer Referenz generiert, sodass jede Operation am Unterobjekt object Beides hat keinen Einfluss auf das übergeordnete Objekt.

Der Nachteil dieser Methode besteht darin, dass der neue Operator während des Konstruktionsprozesses des untergeordneten Objekts nicht verwendet wird, sodass das untergeordnete Objekt keine Attribute des übergeordneten Prototypobjekts erbt Das Kind wird undefiniert sein.

Um dieses Problem zu lösen, können Sie den Prototyp des untergeordneten Objektkonstruktors erneut manuell auf eine Instanz des übergeordneten Objekts setzen:

Code kopieren Der Code lautet wie folgt:

Child.prototype = new Parent()

Dies führt jedoch zu einem weiteren Problem: Der Konstruktor des übergeordneten Objekts wird zweimal aufgerufen, einmal während des Ausleihvorgangs des Konstruktors des übergeordneten Objekts und das andere Mal während des Vererbungsprototypprozesses.

Um dieses Problem zu lösen, müssen wir einen Aufruf an den Konstruktor des übergeordneten Objekts entfernen. Das Ausleihen des Konstruktors kann nicht weggelassen werden, daher kann der letzte Aufruf nur entfernt werden, indem er iterativ kopiert:

Code kopieren Der Code lautet wie folgt:

verlängern2(Kind, Eltern)

Verwenden Sie einfach die zuvor implementierte Methode „extend2()“.
Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn