Saya mencari jawaban yang pasti mengapa memperluas prototipe built-in sangat berat di komunitas pengembang JS. Saya telah menggunakan kerangka JS Prototipe untuk sementara waktu, dan bagi saya melakukan [1,2,3].each(doStuff)
tampak jauh lebih elegan daripada $.each([1,2,3], doStuff)
. Saya tahu bahwa itu menciptakan "polusi namespace," tapi saya masih tidak mengerti mengapa itu dianggap sebagai hal yang buruk. Juga apakah ada penurunan kinerja nyata yang terkait dengan perluasan prototipe bawaan? Terima kasih!
15
for(var ... in ...)
loop menjadi kacau karena fungsi prototipe dilewatkan juga.Jawaban:
Saya menyarankan Anda untuk membaca artikel ini yang saya pikir menjelaskan dengan cukup baik mengapa memperluas objek adalah ide yang buruk, berkaitan dengan Prototipe juga.
Singkatnya:
Kurangnya spesifikasi
Objek host tidak memiliki aturan
Peluang tabrakan
Overhead kinerja
IE DOM berantakan
Bonus: bug browser
sumber
Alasan lain adalah keterbacaan kode / pemeliharaan. Jika pengembang lain (terutama pemula) membaca kode saya dan melihat
[0, 1, 2].foo(...)
, mereka mungkin tidak tahu apa metode foo atau di mana menemukan dokumentasi / sumber untuk itu. Apakah foo adalah ekstensi ke bahasa yang ditambahkan oleh prototype.js, atau oleh perpustakaan lain yang digunakan, atau oleh bagian lain dari kode saya di file lain, atau apakah itu metode JavaScript asli yang tidak mereka ketahui? Mereka perlu mencari dan mungkin tidak segera menemukannya (atau jika ada konflik mereka mungkin tidak menemukannya).Dengan pendekatan jQuery, jika Anda lihat
$.foo(...)
, namespace dari metode foo memperjelas di mana menemukan definisi / dokumentasinya jika Anda tidak tahu apa fungsinya.sumber
Inilah masalah dasarnya: Apa yang terjadi jika Anda memiliki dua alat yang memperpanjang prototipe dengan cara yang tidak kompatibel, atau yang memperluas metode yang biasa disebut dengan cara sedemikian rupa sehingga menghasilkan hasil yang berbeda (ini adalah masalah khusus untuk
for...in
JavaScript), sehingga menyebabkan kode yang bergantung pada pada perilaku normal mereka untuk istirahat?Pada dasarnya, ini adalah masalah yang sama yang Anda miliki ketika Anda salah menggunakan variabel global. Dengan sendirinya, mungkin tidak ada hal buruk yang terjadi. Tapi, itu membuka Anda untuk masalah ketika dua potong kode yang seolah-olah terpisah tiba-tiba menginjak satu sama lain (dan itu menyebalkan untuk debug ketika itu terjadi).
Tentu saja prototype.js cukup terkenal dan sebagian besar alat mengatasi apa yang dilakukannya. Demikian pula, saya yakin ada kasus di mana memperluas prototipe basis adalah hal yang benar untuk dilakukan. Tapi, itu sesuatu untuk didekati dengan hati-hati.
sumber
Tidak yakin apakah ini benar-benar masih menjadi masalah lagi, tetapi pengalaman saya dengan versi Internet Explorer yang lebih lama adalah bahwa kadang-kadang bahkan tidak mungkin untuk memperluas tipe bawaan tertentu.
sumber
Ada dua masalah terpisah di sini. Yang pertama adalah perluasan umum prototipe bawaan, dan lainnya khusus memperluas prototipe DOM. Argumen terhadap perluasan prototipe bawaan:
Array.prototype
atauObject.prototype
dapat memiliki efek knock-on, seperti menambahkan metode ekstensi yang disebutkan dalam satufor...in
lingkaranAdapun memperluas prototipe DOM, argumen potensi bentrokan di atas masih berlaku. Selain itu, node DOM adalah objek host dan karenanya tidak tunduk pada aturan normal objek JavaScript asli. Mereka pada dasarnya dapat melakukan apa yang mereka suka dan tidak berkewajiban untuk menyediakan objek prototipe yang masuk akal atau bahkan mengizinkan properti ekstra ("expando"). IE dalam latihan khusus hak ini, tidak menyediakan prototipe untuk DOM objek sebelum IE 9 dan memiliki berbagai weirdnesses tentang properti di berbagai objek DOM (meskipun Anda properti menugaskan umumnya OK untuk elemen, yang disediakan set apa-apa ini
document.expando
kefalse
.)sumber