Dalam sebagian besar bahasa pemrograman, ada kelas dan objek, dan satu kelas dapat mewarisi kelas lain.
Dalam JavaScript, warisan berbasis prototipe, yang berarti bahwa tidak ada kelas dalam JavaScript, dan sebaliknya satu objek mewarisi objek lain. :)
1. Warisan, Proto
Dalam JavaScript, ketika kelinci objek mewarisi hewan objek lain, itu berarti bahwa akan ada properti khusus dalam objek kelinci: kelinci .__ proto__ = hewan;
Saat mengakses objek kelinci, jika penerjemah tidak dapat menemukan properti dalam kelinci, itu akan mengikuti rantai __proTo__ untuk mencari di objek hewan
Atribut __proto__ dalam chestnut hanya dapat diakses di Chrome dan Firefox. Silakan lihat kastanye:
var hewan = {eats: true} var rabbit = {jumps: true} rabbit .__ proto__ = hewan // warisan (kelinci.eats) // trueAtribut EATS diakses dari objek hewan.
Jika atribut telah ditemukan di objek kelinci, maka atribut proto tidak akan diperiksa.
Mari kita memiliki kastanye lain. Ketika ada juga atribut Eats di subkelas, kelas induk tidak akan diakses.
var hewan = {eats: true} var feduprabbit = {eats: false} feduprabbit .__ proto__ = peringatan hewan (feduprabbit.eats) // falseAnda juga dapat menambahkan fungsi pada hewan, dan juga dapat diakses dalam kelinci.
var hewan = {eat: function () {alert ("I'm full") this.full = true}} var rabbit = {jump: function () { / * sesuatu * /}} kelinci .__ proto__ = hewan(1) Rabbit.eat ():
Fungsi kelinci.eat () dieksekusi dalam dua langkah berikut:
Pertama, penerjemah mencari kelinci.eat. Tidak ada fungsi makan di kelinci, jadi terlihat di sepanjang kelinci .__ proto__ dan menemukannya pada hewan.
Fungsi berjalan dengan ini = kelinci. Nilai ini tidak ada hubungannya dengan atribut __proto__.
Jadi ini.full = true in rabbit:
Mari kita lihat penemuan baru apa yang telah kami buat di sini. Suatu objek memanggil fungsi induk, tetapi ini masih menunjuk pada objek itu sendiri, yang merupakan warisan.
Objek yang dirujuk oleh __proto__ disebut prototipe, dan hewan adalah prototipe kelinci (Catatan Penerjemah: Ini adalah atribut __proTo__ kelinci mengacu pada atribut prototipe hewan)
(2) Cari saat membaca, bukan saat menulis
Saat membaca objek, seperti this.prop, penerjemah mencari properti dalam prototipe.
Saat menetapkan nilai atribut, seperti this.prop = nilai, maka tidak ada alasan untuk mencari, dan atribut ini (prop) akan ditambahkan langsung ke objek ini (ini adalah ini). Hapus obj.prop serupa, hanya menghapus sifat -sifat objek itu sendiri, dan sifat -sifat dalam prototipe tetap utuh.
(3) Tentang proto
Jika Anda membaca panduan ini, di sini kami sebut __proto__, yang diwakili dalam panduan ini sebagai [[prototipe]]. Kedua tanda kurung itu penting karena ada properti lain yang disebut prototipe.
2. Object.create, Object.getPrototypeof
__Proto__ adalah properti non-standar yang disediakan oleh Chrome/Firefox dan tetap tidak terlihat di browser lain.
Semua browser modern kecuali opera (yaitu> 9) mendukung dua fungsi standar untuk menangani masalah prototipe:
Objek.ceate (prop [, props])
Buat objek kosong dengan proto yang diberikan:
var hewan = {eats: true} rabbit = object.create (hewan) peringatan (kelinci.eats) // trueKode di atas membuat objek kelinci kosong dan prototipe diatur ke hewan
Setelah objek kelinci dibuat, kita dapat menambahkan properti ke dalamnya:
var hewan = {eats: true} rabbit = objek.create (hewan) kelinci.jumps = trueParameter kedua dari objek. Fungsi Creat adalah opsional, yang memungkinkan properti diatur seperti objek baru. Ini dihilangkan karena warisan hubungan kita.
(1) Object.getPrototypeOf (OBJ)
Mengembalikan nilai OBJ .__ Proto__. Fungsi ini standar dan dapat digunakan di browser yang tidak dapat secara langsung mengakses atribut __proto__.
var hewan = {eats: true} rabbit = object.create (hewan) peringatan (objek.getPrototypeof (kelinci) === hewan) // trueBrowser modern memungkinkan pembacaan nilai atribut __proto__, tetapi mereka tidak dapat diatur.
3. Prototipe
Ada beberapa cara lintas-browser yang baik untuk mengatur atribut __proto__, yang akan menggunakan fungsi konstruktor. Ingat! Fungsi apa pun membuat objek melalui kata kunci baru.
A Chestnut:
Function Rabbit (Name) {this.name = name} var rabbit = new Rabbit ('John') alert (rabbit.name) // JohnOperasi baru menetapkan properti prototipe ke properti __proTo__ dari objek kelinci.
Mari kita lihat prinsipnya, misalnya, objek kelinci baru, yang mewarisi hewan.
var hewan = {eats: true} function rabbit (name) {this.name = name} rabbit.prototype = animalvar rabbit = rabbit baru ('john') peringatan (kelinci.eats) // true, karena kelinci .__ proto__ == hewanRabbit.prototype = hewan literal berarti: set __proto__ = hewan untuk semua objek yang dibuat oleh kelinci baru
4. Objek Cross-Browser.Create (Proto)
Fungsi Object.Create (prop) sangat kuat karena memungkinkan warisan langsung dari objek yang diberikan. Itu dapat disimulasikan dengan kode berikut:
function wolor (proto) {function f () {} f.prototype = proto return baru f}warisan (hewan) persis setara dengan objek.create (hewan), mengembalikan objek kosong, dan objek .__ proto__ = hewan.
A Chestnut:
var hewan = {eats: true} var rabbit = waris (hewan) peringatan (kelinci.eats) // truealert (rabbit.hasownproperty ('eats')) // false, dari prototipeMari kita lihat apa prinsipnya:
fungsi warisan (proto) {function f () {} // (1) f.prototype = proto // (2) mengembalikan f baru () // (3)}(1) Fungsi baru dibuat, dan fungsi tidak menetapkan atribut apa pun untuk ini, jadi `baru F` akan membuat objek kosong.
(2) `f.prototype` diatur ke Proto
(3) `new` f membuat objek kosong, objek` __proto__ = f.prototype`
(4) Bingo! Kami mendapatkan objek kosong yang mewarisi `proto`
Fungsi ini banyak digunakan di berbagai perpustakaan dan kerangka kerja.
Fungsi Anda menerima objek dengan opsi
/ * Opsi berisi pengaturan menu: lebar, tinggi dll */menu fungsi (opsi) {// ...} Anda ingin mengatur menu fungsi opsi tertentu (opsi) {options.width = options.width || 300 // Atur nilai default // ...}. . . Tetapi mengubah nilai parameter dapat menghasilkan beberapa hasil yang salah, karena opsi dapat digunakan dalam kode eksternal. Solusi adalah mengkloning objek opsi, menyalin semua atribut ke objek baru, dan memodifikasinya di objek baru.
Bagaimana cara menyelesaikan masalah ini dengan warisan? Opsi PS dapat menambah pengaturan, tetapi tidak dapat dihapus.
Larutan
Anda dapat mewarisi opsi dan memodifikasi atau menambahkan properti baru di subkelasnya.
function warisasi (proto) {function f () {} f.prototype = proto return baru f} function menu (opsi) {var opts = warisan (opsi) opts.width = opts.width || 300 // ...}Semua operasi hanya berlaku di sub-objek. Ketika metode menu berakhir, kode eksternal masih dapat menggunakan objek opsi yang tidak dimodifikasi. Hapus operasi sangat penting di sini. Jika lebar adalah properti dalam prototipe, hapus opts.width tidak akan berpengaruh
5. HasownProperty
Semua objek memiliki fungsi hasownproperty, yang dapat digunakan untuk mendeteksi apakah suatu properti itu sendiri atau prototipe.
A Chestnut:
Function Rabbit (name) {this.name = name} rabbit.prototype = {eats: true} var rabbit = rabbit baru ('John') alert (rabbit.hasownproperty ('eats')) // false, in prototipealert (rabbit.hasownproperty ('name') // in prototipeal (rabbit.hasownproperty ('name') // in prototipeal (rabbit.hasownproperty ('in' in) // in prototipeal (rabbit.hasownproperty ('in' in)6. Looping dengan/tanpa properti warisan
untuk..di loop output semua properti objek, termasuk miliknya dan prototipe.
Function Rabbit (name) {this.name = name} rabbit.prototype = {eats: true} var rabbit = rabbit baru ('John') untuk (var p dalam kelinci) {waspada (p + "=" + kelinci [p]) // output keduanya "nama" dan "makan"}Gunakan HasownProperty untuk memfilter sifat -sifat objek:
Function Rabbit (name) {this.name = name} rabbit.prototype = {eats: true} var rabbit = rabbit baru ('John') untuk (var p in rabbit) {if (! rabbit.hasownproperty (p)) lanjutkan // filter "out" out "name (p +" = " + rabbit [p]) /7. Ringkasan
JavaScript mengimplementasikan warisan melalui proto atribut khusus
Saat mengakses properti suatu objek, jika penerjemah tidak dapat menemukannya di objek, ia akan terus mencari properti fungsi, ini menunjuk ke objek, bukan prototipe.
Tetapkan obj.prop = nilai, hapus obj.prop
Kelola Proto:
Chrome dan Firefox dapat secara langsung mengakses atribut __proto__ objek. Sebagian besar browser modern mendukung akses hanya baca menggunakan objek.getPrototypeOf (OBJ).
Object.create (Proto) dapat menghasilkan objek anak kosong dengan proto yang diberikan, atau mencapai fungsi yang sama melalui kode berikut:
fungsi warisan (proto) {function f () {} f.prototype = proto return new f ()}Metode lain:
untuk..di loop output semua properti objek (termasuk miliknya dan prototipe) dan rantai prototipe objek.
Jika prop properti milik objek obj maka obj.hasownproperty (prop) mengembalikan benar, jika tidak salah.