Harap lupakan semua pengetahuan berorientasi objek yang Anda pelajari sebelumnya. Pertimbangkan saja situasi balap di sini. Ya, ini balapan.
Baru -baru ini saya menonton 24 Hours of Le Mans, sebuah acara populer di Prancis. Mobil tercepat disebut prototipe Le Mans. Meskipun mobil -mobil ini dibuat oleh produsen seperti "Audi" atau "Peugeot", mereka bukan jenis mobil yang Anda lihat di jalan atau di jalan raya. Mereka dibuat khusus untuk acara daya tahan berkecepatan tinggi.
Pabrikan menginvestasikan sejumlah besar uang untuk mengembangkan, merancang, dan memproduksi mobil -mobil prototipe ini, dan insinyur selalu berusaha membuat proyek ini menjadi ekstrem. Mereka melakukan berbagai percobaan pada paduan, biofuel, teknologi pengereman, komposisi majemuk dan karakteristik keselamatan ban. Seiring waktu, beberapa teknik dalam percobaan ini telah berulang kali ditingkatkan dan memasuki lini produk kendaraan utama. Beberapa teknologi di dalam kendaraan yang Anda kendarai mungkin telah memulai debutnya di prototipe balap.
Anda juga dapat mengatakan bahwa kendaraan utama ini mewarisi prototipe teknis dari mobil balap.
Sampai sekarang, kami memiliki dasar untuk membahas masalah prototipe dan warisan dalam JavaScript. Meskipun tidak sebagus pola warisan klasik yang Anda ketahui dalam C ++, Java, atau C#, itu sama kuat dan berpotensi lebih fleksibel.
JavaScript penuh dengan objek, yang mengacu pada objek dalam pengertian tradisional, yaitu, "satu entitas yang berisi keadaan dan perilaku." Misalnya, array dalam JavaScript adalah objek yang berisi beberapa nilai dan berisi metode dorongan, terbalik, dan pop.
var myArray = [1, 2]; myarray.push (3); myarray.reverse (); myarray.pop (); var length = myarray.length;
Sekarang pertanyaannya adalah, dari mana dorong berasal? Bahasa statis yang kami sebutkan sebelumnya menggunakan "sintaks kelas" untuk menentukan struktur objek, tetapi JavaScript adalah bahasa tanpa "sintaks kelas" dan tidak dapat mendefinisikan setiap objek array menggunakan sintaks "kelas" array. Dan karena JavaScript adalah bahasa yang dinamis, kita dapat menempatkan metode pada objek karena kita benar -benar membutuhkannya. Sebagai contoh, kode berikut mendefinisikan objek titik yang digunakan untuk mewakili titik dalam ruang dua dimensi, dan juga mendefinisikan metode ADD.
var point = {x: 10, y: 5, add: function (OtherPoint) {this.x += OtherPoint.x; this.y += OtherPoint.y; }};Namun, praktik di atas tidak terlalu terukur. Kita perlu memastikan bahwa setiap objek titik berisi metode tambah, dan kami juga ingin semua objek titik untuk berbagi implementasi metode ADD yang sama, alih -alih menambahkan metode ini secara manual ke setiap objek titik. Di sinilah prototipe berperan.
Dalam JavaScript, setiap objek tetap tersembunyi - referensi ke objek lain, juga dikenal sebagai prototipe. Array yang kami buat sebelum merujuk objek prototipe, dan begitu pula objek titik yang kami buat sendiri. Seperti disebutkan di atas, referensi prototipe disembunyikan, tetapi ada juga implementasi ecmascript (nama resmi JavaScript) yang dapat mengakses referensi prototipe ini melalui atribut __proto__ suatu objek (seperti Google Chrome). Secara konseptual, kita dapat memperlakukan objek sebagai hubungan yang mirip dengan yang diwakili dalam Gambar 1-Prototipe.
Gambar 1
Ke depan, pengembang akan dapat menggunakan fungsi Object.getPrototype dari sebagai atribut __proto__ untuk mendapatkan referensi ke prototipe objek. Pada saat penulisan artikel ini, fungsi Object.getPrototypeOf sudah dapat digunakan di browser Google Chrome, Firefox dan IE9. Lebih banyak browser akan mengimplementasikan fitur ini di masa depan karena sudah menjadi bagian dari standar ecmascript. Kami dapat menggunakan kode berikut untuk membuktikan bahwa objek myArray dan dot yang kami buat merujuk ke dua objek prototipe yang berbeda.
Untuk sisa artikel ini, saya akan menggunakan silang fungsi __proTo__ dan objek. Harus diingat bahwa itu (__proto__) bukan standar, dan objek.getPototipe fungsi adalah metode yang disarankan untuk melihat prototipe objek.
Apa yang membuat prototipe begitu istimewa?
Kami belum menjawab pertanyaan ini: dari mana dorong dalam array berasal? Jawabannya adalah: itu berasal dari objek prototipe myArray. Gambar 2 adalah tangkapan layar dari skrip debugger di Chrome. Kami telah memanggil Object.getPrototype dari metode untuk melihat objek prototipe myArray.
Gambar 2
Perhatikan bahwa ada banyak metode dalam objek prototipe MyArray, termasuk yang disebut metode push, pop, dan terbalik dalam contoh kode. Oleh karena itu, metode push tidak termasuk objek prototipe, tetapi bagaimana metode MyArray merujuknya?
myarray.push (3);
Langkah pertama untuk memahami cara kerjanya adalah menyadari bahwa prototipe tidak istimewa. Prototipe hanyalah objek normal. Anda dapat menambahkan metode, properti ke prototipe dan memperlakukannya sebagai objek JavaScript lainnya. Namun, untuk menerapkan pernyataan "babi" dalam novel George Orwell "Peternakan Hewan" - semua objek harus sama, tetapi beberapa objek (mereka yang mengikuti aturan) lebih setara daripada yang lain.
Objek prototipe dalam JavaScript memang istimewa karena mengikuti aturan berikut. Ketika kami memberi tahu JavaScript bahwa kami ingin memanggil metode dorong objek, atau membaca properti X objek, runtime pertama akan mencari objek itu sendiri. Jika runtime tidak dapat menemukan apa yang diinginkannya, itu mengikuti referensi __proto__ dan prototipe objek untuk mencari anggota. Ketika kami memanggil metode dorong MyArray, JavaScript tidak menemukan metode push pada objek MyArray, tetapi pada objek prototipe MyArray, jadi JavaScript memanggil metode ini (lihat Gambar 3).
Gambar 3
Perilaku yang dijelaskan di atas mengacu pada objek itu sendiri yang mewarisi metode atau properti apa pun pada prototipe. Dalam JavaScript, warisan sebenarnya dicapai tanpa menggunakan sintaks kelas. Sama seperti mobil yang mewarisi teknologi yang sesuai dari prototipe balap, objek JavaScript juga dapat mewarisi fitur fungsional dari objek prototipe.
Gambar 3 juga menunjukkan bahwa setiap objek array juga dapat mempertahankan keadaan dan anggotanya sendiri. Saat meminta atribut panjang myArray, JavaScript akan mendapatkan nilai atribut panjang di myArray tanpa membaca nilai yang sesuai dalam prototipe. Kita dapat "menimpa" metode dorong dengan menambahkan metode seperti dorongan ke objek. Ini secara efektif akan menyembunyikan implementasi metode push dalam prototipe.
Keajaiban nyata dari prototipe dalam JavaScript adalah bagaimana banyak objek mempertahankan referensi ke objek prototipe yang sama. Misalnya, jika kita membuat dua array seperti ini:
var myArray = [1, 2]; var youarray = [4, 5, 6];
Kemudian kedua array ini akan berbagi objek prototipe yang sama, dan kode berikut mengevaluasi ke True:
Object.getPrototypeOf (myArray) === object.getProtOpyOf (yourArray);
Jika kita merujuk pada metode push pada dua objek array, JavaScript akan mencari metode push yang dibagikan pada prototipe.
Gambar 4
Objek prototipe dalam JavaScript memberikan fungsi warisan, dan pada saat yang sama, berbagi metode ini diimplementasikan. Prototipe juga dirantai. Dengan kata lain, karena objek prototipe hanyalah objek, satu objek prototipe dapat dipertahankan ke referensi ke objek prototipe lain. Jika Anda meninjau kembali Gambar 2, Anda dapat melihat bahwa properti __proTo__ dari prototipe adalah nilai non-nol yang menunjuk ke prototipe lain. Ketika JavaScript mencari anggota seperti metode push, ia memeriksa setiap objek di sepanjang rantai referensi prototipe sampai ditemukan, atau mencapai ujung rantai prototipe. Rantai prototipe membuka jalur yang fleksibel untuk warisan dan berbagi.
Pertanyaan berikutnya yang mungkin Anda tanyakan adalah: Bagaimana cara mengatur referensi prototipe ke objek kustom tersebut? Misalnya, objek titik yang digunakan sebelumnya, bagaimana saya bisa menambahkan metode tambah ke objek prototipe dan mewarisi metode dari beberapa objek titik? Sebelum menjawab pertanyaan ini, kita perlu melihat fungsinya.
Fungsi dalam JavaScript juga merupakan objek. Pernyataan seperti itu membawa beberapa hasil penting, dan kami tidak akan membahas semua hal dalam artikel ini. Di antara mereka, kemampuan untuk menetapkan fungsi ke variabel dan meneruskan fungsi sebagai parameter ke fungsi lain merupakan paradigma dasar dari ekspresi pemrograman JavaScript modern.
Yang perlu kita perhatikan adalah bahwa fungsi itu sendiri adalah objek, sehingga fungsi dapat memiliki metode, properti, dan referensi sendiri objek prototipe. Mari kita bahas arti kode berikut.
// Ini akan mengembalikan true: typeOf (array) === "function" // Ekspresi seperti itu juga: objek.getPrototypeOf (array) === Object.getPrototypeOf (function () {}) // Ekspresi tersebut sama: array.prototype! = NullBaris pertama dalam kode membuktikan bahwa array dalam JavaScript adalah fungsi. Kita akan melihat cara memanggil fungsi array untuk membuat objek array baru. Baris kode berikutnya membuktikan bahwa objek array menggunakan prototipe yang sama dengan objek fungsi lainnya, seperti yang kita lihat bahwa prototipe yang sama dibagi antara objek array. Baris kode terakhir membuktikan bahwa fungsi array memiliki properti prototipe, dan properti prototipe ini menunjuk ke objek yang valid. Properti prototipe ini sangat penting.
Setiap objek fungsi dalam JavaScript memiliki properti prototipe. Jangan pernah membingungkan atribut __proto__ dari properti prototipe ini. Mereka memiliki tujuan yang berbeda, mereka juga tidak menunjuk ke objek yang sama.
// kembalikan trueObject.getPrototypeOf (array)! = Array.prototype
Array .__ Proto__ menyediakan prototipe array. Harap perlakukan itu sebagai objek yang diwarisi oleh fungsi array.
Array.protoype menyediakan objek prototipe untuk semua array. Dengan kata lain, ini menyediakan objek prototipe objek array seperti MyArray, dan juga berisi metode yang akan diwariskan oleh semua array. Kami dapat menulis beberapa kode untuk membuktikan fakta ini.
// truearray.prototype == object.getPrototypeOf (myArray) // Ini juga truearray.prototype == object.getPrototypeOf (yourArray);
Kami juga dapat menggunakan pengetahuan baru ini untuk mengecat ulang diagram sebelumnya.
Gambar 5
Berdasarkan apa yang Anda ketahui, bayangkan proses membuat objek baru dan membuat objek baru berperilaku seperti array. Salah satu caranya adalah dengan menggunakan kode berikut.
// Buat objek kosong baru var o = {}; // diwarisi dari prototipe yang sama, objek array o .__ proto__ = array.prototype; // Sekarang kita dapat memanggil metode apa pun dari array ... o.push (3);Meskipun kode ini menarik dan berhasil, masalahnya adalah bahwa tidak setiap lingkungan JavaScript mendukung properti objek __proTo__. Untungnya, JavaScript memang memiliki mekanisme standar untuk membuat objek. Ini hanya membutuhkan satu operator untuk membuat objek baru, dan mengatur referensi __proto__ dari objek baru, yaitu operator "baru".
var o = array baru (); o.push (3);
Operator baru di JavaScript memiliki tiga tugas dasar. Pertama, itu menciptakan objek kosong baru. Selanjutnya, itu akan mengatur properti __proto__ dari objek baru agar sesuai dengan properti prototipe dari fungsi yang dipanggil. Akhirnya, operator memanggil fungsi, meneruskan objek baru sebagai referensi "ini". Jika Anda ingin memperpanjang dua baris kode terakhir, itu akan menjadi situasi berikut:
var o = {}; o .__ proto__ = array.prototype; array.call (o); o.push (3);Metode panggilan fungsi memungkinkan Anda untuk menentukan objek yang dirujuk oleh "ini" di dalam fungsi saat memanggil fungsi. Tentu saja, penulis fungsi perlu menerapkan fungsi seperti itu dalam kasus ini. Setelah penulis menciptakan fungsi seperti itu, ia dapat disebut konstruktor.
Konstruktor
Konstruktor sama dengan fungsi biasa, tetapi memiliki dua properti khusus berikut.
Array adalah contoh konstruktor. Fungsi array perlu digunakan dengan operator baru, dan surat awal array dikapitalisasi. JavaScript termasuk array sebagai fungsi bawaan, dan siapa pun dapat menulis konstruktor mereka sendiri. Bahkan, kita akhirnya bisa menulis konstruktor untuk objek titik yang dibuat sebelumnya.
var point = function (x, y) {this.x = x; this.y = y; this.add = function (OtherPoint) {this.x += OtherPoint.x; this.y += OtherPoint.y; }} var p1 = titik baru (3, 4); var p2 = titik baru (8, 6); p1.add (p2);Dalam kode di atas, kami menggunakan operator baru dan fungsi titik untuk membuat objek titik, yang memiliki atribut X dan Y dan metode tambah. Anda dapat membayangkan hasil akhir seperti yang ditunjukkan pada Gambar 6.
Gambar 6
Masalahnya sekarang adalah masih ada metode add yang terpisah di setiap objek poin kami. Menggunakan prototipe dan warisan yang kami pelajari, kami lebih suka mentransfer metode tambah objek titik dari setiap instance titik ke titik. Prototype. Untuk mencapai efek mewarisi metode ADD, yang perlu kita lakukan adalah memodifikasi objek point.prototype.
var point = function (x, y) {this.x = x; this.y = y;} point.prototype.add = function (OtherPoint) {this.x += OtherPoint.x; this.y += OtherPoint.y;} var p1 = titik baru (3, 4); var p2 = titik baru (8, 6); p1.add (p2);Misi selesai! Kami baru saja menyelesaikan mode warisan prototipe di JavaScript!
Gambar 7
Meringkaskan
Saya harap artikel ini akan membantu Anda mengungkap misteri konsep prototipe JavaScript. Apa yang saya lihat pada awalnya adalah bagaimana prototipe memungkinkan suatu objek untuk mewarisi fungsi dari objek lain, dan kemudian melihat cara menggabungkan operator dan konstruktor baru untuk membangun objek. Apa yang disebutkan di sini hanyalah langkah pertama untuk membuka kunci kekuatan dan fleksibilitas prototipe objek. Artikel ini mendorong Anda untuk menemukan dan mempelajari informasi baru tentang prototipe dan bahasa JavaScript untuk diri Anda sendiri.
Juga, tolong mengemudi dengan hati -hati. Anda tidak akan pernah tahu apa (cacat) teknologi kendaraan yang bepergian di jalan ini akan mewarisi dari prototipe mereka.
Tautan Asli: Skrip Junkie Terjemahan: Bole Online - EMJE