Apa artinya Javascript adalah bahasa berbasis prototipe?

255

Salah satu keuntungan utama dengan Javascript adalah bahwa ia adalah bahasa berbasis prototipe.

Tapi apa artinya Javascript berbasis prototipe, dan mengapa itu keuntungan?

Jonas Pegerfalk
sumber
3
Jawaban ini menjelaskan semua yang perlu Anda ketahui tentang pewarisan prototypal: stackoverflow.com/a/16872315/783743
Aadit M Shah

Jawaban:

291

Warisan prototipe adalah bentuk penggunaan kembali kode berorientasi objek . Javascript adalah satu-satunya bahasa berorientasi obyek [utama] yang menggunakan pewarisan prototypal. Hampir semua bahasa berorientasi objek lainnya adalah klasik.

Dalam warisan klasik , programmer menulis kelas, yang mendefinisikan objek. Beberapa objek dapat dipakai dari kelas yang sama, sehingga Anda memiliki kode di satu tempat yang menggambarkan beberapa objek di program Anda. Kelas-kelas kemudian dapat diatur ke dalam hierarki, melanjutkan penggunaan kembali kode. Lebih banyak kode umum disimpan di kelas tingkat yang lebih tinggi, yang darinya kelas bawah mewarisi. Ini berarti bahwa suatu objek membagikan kode dengan objek lain dari kelas yang sama, serta dengan kelas induknya.

Dalam bentuk pewarisan prototypal , objek mewarisi langsung dari objek lain. Semua bisnis tentang kelas hilang. Jika Anda menginginkan objek, Anda cukup menulis objek. Tetapi penggunaan kembali kode masih merupakan hal yang berharga, sehingga objek diizinkan untuk dihubungkan bersama dalam suatu hierarki. Dalam javascript, setiap objek memiliki tautan rahasia ke objek yang membuatnya, membentuk rantai. Ketika suatu objek diminta untuk properti yang tidak dimilikinya, objek induknya akan diminta ... teruskan rantai sampai properti ditemukan atau sampai objek root tercapai.

Setiap fungsi dalam JavaScript (yang merupakan objek itu sendiri) sebenarnya memiliki anggota yang disebut "prototipe", yang bertanggung jawab untuk memberikan nilai ketika suatu objek diminta untuk mereka. Memiliki anggota ini memungkinkan mekanisme konstruktor (dimana objek dibangun dari fungsi) bekerja. Menambahkan properti ke prototipe objek fungsi akan membuatnya tersedia untuk objek yang dibangun, serta semua objek yang mewarisi darinya.

Keuntungan

Mungkin tidak ada aturan yang keras dan cepat mengapa pewarisan prototypal merupakan bentuk penggunaan kembali kode yang menguntungkan. Penggunaan kembali kode itu sendiri menguntungkan, dan pewarisan prototypal adalah cara yang masuk akal untuk melakukannya. Anda mungkin berpendapat bahwa pewarisan prototipe adalah model penggunaan kembali kode yang cukup sederhana , dan kode itu dapat digunakan kembali secara langsung . Tetapi bahasa klasik tentu saja dapat mencapai hal ini juga.

Sidenote: @Andrew Hedges membuat poin yang bagus, bahwa sebenarnya ada banyak bahasa prototipe. Perlu dicatat bahwa yang lain ini ada, tetapi juga patut dicatat bahwa tidak ada dari mereka yang mendekati arus utama. NewtonScript tampaknya memiliki daya tarik untuk sementara waktu, tetapi meninggal dengan platformnya. Dimungkinkan juga untuk memperluas beberapa bahasa modern dengan cara yang menambahkan kemampuan prototypal.

keparo
sumber
9
Hei Kelly. Sementara JavaScript sejauh ini merupakan bahasa prototypal yang paling populer, ada banyak lainnya: en.wikipedia.org/wiki/Prototype-based_programming#Languages
Andrew Hedges
2
Hei Andrew. Poin yang bagus. Seharusnya aku lebih jelas. Saya akan mencatatnya.
keparo
3
Silakan baca ini juga developer.mozilla.org/en/JavaScript/Guide/…
pramodc84
1
+1 untuk jawaban yang bagus. Satu komentar kecil: Bagi saya, warisan klasik tampaknya lebih "langsung" daripada prototypal. Bahkan, saya benar-benar melihat objek prototipe sebagai hubungan belaka (ke objek lain), sedangkan dalam OOP yang dikompilasi saya menganggap kelas dasar sebagai "warisan langsung". Dengan demikian, objek prototypal dirantai-bersama daripada diwarisi (warisan agak dipalsukan). Adakah pikiran?
Tahanan NOL
3
@PrisonerZERO: Saya berpendapat bahwa pewarisan prototypal lebih langsung daripada klasik. Alih-alih objek B menunjuk ke kelas yang mewarisi dari kelas yang menolak titik A, itu menunjuk langsung ke objek A dan mengatakan "Aku hanya seperti objek itu, kecuali ...". Hal besar tentang pewarisan prototypal, dan hal yang tampaknya paling sulit bagi kebanyakan orang untuk diinternalisasi, adalah bahwa ia tidak membedakan contoh dari jenis. Setiap objek adalah baik jenis dan contoh. Perbedaan antara keduanya adalah buatan dan disengaja, dan biasanya merupakan gejala terjebak dalam pola pikir berorientasi kelas.
cHao
54

Bahasa berbasis prototipe, tidak membuat perbedaan kelas vs objek: ia hanya memiliki objek. Bahasa berbasis prototipe memiliki gagasan tentang objek prototipe, objek yang digunakan sebagai templat untuk mendapatkan properti awal untuk objek baru. Objek apa pun dapat menentukan propertinya sendiri, baik saat Anda membuatnya atau pada saat dijalankan. Selain itu, objek apa pun dapat dikaitkan sebagai prototipe untuk objek lain , memungkinkan objek kedua berbagi properti objek pertama.

Guido
sumber
6
Penjelasan yang sangat bagus, tetapi sedikit menyesatkan dengan komentar tentang "templat untuk properti awal". Jika Anda mengubah prototipe SETELAH instantiasi objek, objek itu masih menerima fungsi-fungsi tersebut.
nickf
32

Pemrograman berbasis prototipe adalah gaya pemrograman berorientasi objek di mana kelas tidak ada, dan penggunaan kembali perilaku (atau pewarisan dalam bahasa berbasis kelas) dilakukan dengan mengkloning objek yang ada yang berfungsi sebagai prototipe.

CMS
sumber
Apakah Anda masih merasakan hal ini? Karena jika demikian maka ini adalah penjelasan pertama yang benar-benar hanya "klik" dengan saya.
Chazt3n
11

Keuntungan / kerugiannya adalah, kita dapat membuat objek jenis baru pada saat run time tanpa perlu mendefinisikan kelas (kode statis). Seperti kebanyakan fitur, terserah pengembang untuk mengubahnya ke keuntungan / kerugian.

Di atas dimungkinkan karena objek pada dasarnya adalah fungsi dalam skrip java (penutup juga).

questzen
sumber
Objek dinamis adalah manfaat javascript, tetapi mereka tidak benar-benar terkait dengan javascript sebagai bahasa prototipal atau fungsional. Dalam banyak bahasa klasik Anda dapat membuat objek dinamis saat runtime. Penutupan agak tidak terkait, juga.
keparo
2
Kelas tidak harus berupa kode statis - lihatlah Python, di mana kelas adalah objek itu sendiri, dan dibangun dari metaclasses yang juga merupakan objek.
Tomasz Zieliński
6

Alih-alih mendeklarasikan struktur kelas, Anda bisa membuat objek dengan tipe yang sama, dan menambahkan definisi mereka kapan saja Anda suka menggunakan prototipe objek. Ini lebih fleksibel daripada cara normal dalam melakukan sesuatu.

Greg
sumber
6

Jika Anda hanya menggunakan objek saat runtime alih-alih kelas saat kompilasi untuk membangun objek baru, ini membuka kemungkinan memperluas objek tanpa mengetahui detailnya. Tentu saja, itu bisa menjadi kerugian cukup cepat tergantung penggunaannya. Saya tidak membuat asumsi tentang bahasa di sini, jadi itu berlaku untuk bahasa selain javascript yang tidak dinamis.

myobject.prototype=unkownobject;
myobject.newproperty=1;

Anda bisa mendapatkan objek dari mana saja; kode Anda sendiri, dari jaringan, dari database, dari tautan eksternal dan sebagainya.

Perhatikan bahwa suatu bahasa tidak harus mengimplementasikan pewarisan prototipe seperti javascript. Dalam javascript, objek prototipe hanya dibagikan, demikian juga propertinya, di antara pewarisnya. Alternatifnya adalah menyalin semua properti prototipe ke objek baru. Setiap pendekatan memiliki kelebihan dalam situasi yang berbeda. Saya lebih suka yang kedua tetapi bukan itu yang dilakukan javascript.

artificialidiot
sumber
6

Setelah membaca semua jawaban, inilah kesimpulannya

1) Warisan di mana objek diwarisi langsung dari objek lain

2) Itu tidak menggunakan kelas

3) Juga disebut pemrograman berbasis instance atau pemrograman berorientasi prototipe tanpa kelas

4) Penggunaan kembali perilaku dilakukan dengan mengkloning objek yang ada yang berfungsi sebagai prototipe

5) Objek yang digunakan sebagai templat dari objek baru mendapatkan properti awal

Sunil Garg
sumber