Rumah >hujung hadapan web >tutorial js >Penggunaan Pragmatik Monyet dalam JavaScript
mata teras
Artikel ini dikaji semula oleh Moritz Kröger dan Tom Greco. Terima kasih kepada semua pengulas rakan sebaya di SitePoint untuk mendapatkan kandungan SitePoint dengan sebaik -baiknya!
Dalam artikel ini, kita akan mempelajari apa patch monyet dan langkah melalui beberapa contoh yang berbeza untuk menggunakannya untuk mengubah fungsi widget pihak ketiga untuk memenuhi keperluan kita.
Apakah patch monyet?
Patch Monyet (MP) adalah teknik yang digunakan untuk menimpa, memperluaskan, dan bahkan menindas tingkah laku lalai segmen kod tanpa mengubah kod sumber asalnya. Ini dilakukan dengan menggantikan tingkah laku asal dengan versi fix
.Artikel ini akan menggunakan widget kotak maklum balas yang sedia ada yang memaparkan tetingkap pop timbul yang mudah dan boleh disapu (ditunjukkan dalam imej di bawah) yang mengandungi borang maklum balas.
Satu lagi pengubahsuaian yang saya buat adalah untuk menghapuskan ekspresi fungsi panggilan (Iife) di sekitar kod. Ini dilakukan untuk memberi tumpuan kepada teknologi MP.
Anda boleh mencari keseluruhan contoh di Plunker, termasuk patch monyet yang dibincangkan dalam artikel ini. Bukankah monyet patch amalan buruk? Sebelum kita mula, mari kita jelaskan: Ya, MP dianggap sebagai amalan buruk-Evil eval , pengaturcaraan penting, struktur data yang berubah-ubah, mengikat dua hala begitu tunggu. Jika anda menggunakan salah satu daripada ini, terdapat kemungkinan besar kumpulan orang yang memberitahu anda bahawa anda melakukan sesuatu yang salah dan ini atau yang harus ditukar agar sesuai dengan keadaan yang lebih baik. Tetapi seperti biasa, terdapat alat dan teknologi yang berbeza, dan kebolehgunaannya berbeza -beza dalam senario tertentu. Kadang -kadang, sesuatu yang kelihatan melampau, gila, atau hanya buruk boleh menjadi usaha terakhir dalam situasi tertentu. Malangnya, kerana beberapa amalan dianggap buruk, anda tidak dapat mencari banyak artikel untuk menggambarkan bagaimana melakukan perkara yang salah dengan cara yang betul.
Keadaan yang diterangkan di sini mungkin tidak wajar, tolaknya dengan melampau dengan widget palsu untuk menunjukkan pilihan anda. Kemudian, sebagai pembaca, anda perlu memutuskan sama ada anda suka apa yang anda lihat. Jika tidak ada yang lain, selepas membaca artikel ini, anda akan mempunyai pemahaman yang lebih baik untuk membantah MP.
Sebelum kita menggali lebih mendalam ke dalam teknologi ini, mari kita lihat terlebih dahulu apa yang ingin kita capai. Widget yang diubahsuai mempunyai beberapa bau kod, dan kami ingin menyelesaikan masalah ini. warna latar belakang hardcoded
log konsol Nevil blok panggilan pelayan iklan
Salah satu konsep utama MP adalah untuk mendapatkan fungsi sedia ada dan meningkatkannya sebelum atau selepas memanggil kod asal menggunakan tingkah laku tersuai. Tetapi memanggil pelaksanaan asal tidak selalu diperlukan, kerana kadang -kadang anda hanya mahu menggantikannya dengan tindakan tersuai. Pendekatan ini sangat baik untuk membantu kami menyelesaikan masalah warna latar belakang yang keras. Lokasi di mana MP digunakan mesti dimuatkan dan disediakan dengan pelaksanaan asal. Umumnya, anda harus berusaha untuk mendapatkan perubahan yang hampir dengan matlamat anda, tetapi ingat bahawa pelaksanaan matlamat mungkin berubah dari masa ke masa. Bagi contoh kami, Inisialisasi dan MP akan pergi ke fail main.js. Melihat pelaksanaan widget, kita dapat melihat bahawa terdapat objek kotak maklum balas sebagai akar widget. Kemudian, fungsi ToggleError akan dilaksanakan pada prototaipnya. Sejak JavaScript adalah bahasa dinamik yang objeknya boleh diubahsuai pada masa runtime, semua yang kita akan lakukan adalah menggantikan ToggleError dengan kaedah tersuai kami. Satu -satunya perkara yang perlu diperhatikan ialah menyimpan tandatangan (nama dan parameter lulus) yang sama. Pelaksanaan baru kini hanya menambah kelas ralat ke elemen yang diberikan, yang membolehkan kami menetapkan warna latar belakang melalui CSS. Kaedah Peningkatan Dalam contoh sebelumnya, kita melihat bagaimana untuk mengatasi pelaksanaan asal dengan menyediakan kaedah kita sendiri. Sebaliknya, pemprosesan log konsol hanya perlu menyaring panggilan tertentu dan menindasnya. Kunci kejayaan adalah untuk mengkaji kod yang anda benamkan dan cuba memahami aliran kerja. Biasanya, ini dilakukan dengan melancarkan konsol pemaju dalam penyemak imbas pilihan anda dan mengintip melalui sumber yang dimuatkan, menambah titik putus, dan menyahpepijat bahagian kod objek untuk memahami fungsinya. Walau bagaimanapun, kali ini, anda hanya perlu membuka pelaksanaan dalam contoh plunker yang dipanggil vendor/jQuery.feedbackbox.js dalam tab lain. Dengan melihat mesej debug, kita dapat melihat bahawa setiap daripada mereka bermula dengan Feedbackbox: . Oleh itu, cara mudah untuk mencapai apa yang kita mahu adalah untuk memintas panggilan asal, periksa teks yang disediakan untuk ditulis, dan hubungi kaedah asal hanya jika ia tidak mengandungi prompt debug. Untuk melakukan ini, mari kita simpan pertama Console.log asal dalam pembolehubah untuk kegunaan kemudian. Kemudian sekali lagi, kami mengatasi pelaksanaan asal dengan pelaksanaan tersuai kami, yang pertama memeriksa jika teks harta yang disediakan adalah jenis rentetan, dan jika ya, cek jika ia mengandungi kotak maklum balas substring:. Jika ya, kami tidak akan berbuat apa -apa, jika tidak, kami akan melaksanakan kod konsol asal dengan memanggil kaedah pemohon. Perhatikan bahawa kaedah ini mengambil konteks sebagai parameter pertama, yang bermaksud bahawa kaedah itu harus dipanggil pada objek itu, serta pemboleh ubah argumen sihir. Yang terakhir adalah pelbagai parameter yang asalnya dihantar ke panggilan konsol.log asal. Nota: Anda mungkin tertanya -tanya mengapa kami tidak hanya mengemukakan atribut teks. Nah, Console.log sebenarnya boleh dipanggil dengan parameter tak terhingga, yang akhirnya akan disambungkan ke satu output teks. Oleh itu, bukannya menentukan semua parameter ini (yang boleh menjadi sangat sukar untuk kemungkinan yang tidak terhingga), kami hanya meneruskan semua kandungan yang masuk. Memintas panggilan AJAX Terakhir tetapi tidak kurang, mari kita lihat bagaimana menyelesaikan masalah pelayan iklan. Mari lihat fungsi init widget lagi: Idea pertama mungkin membuka penyemak imbas dan mencari cara untuk mengatasi plugin jQuery. Bergantung pada seberapa baik kemahiran carian anda, anda mungkin atau tidak dapat mencari jawapan yang betul. Tetapi mari kita berhenti dan fikirkan apa yang berlaku di sini. Tidak kira apa jQuery lakukan dengan kaedah Ajax, ia akhirnya mewujudkan XMLHTTPREQUEST asli pada satu ketika. mari kita lihat bagaimana ia berfungsi di belakang tabir. Contoh paling mudah yang terdapat di MDN menunjukkan kepada kita ini: kita melihat contoh XMLHTTPREQUEST baru yang dibuat. Ia mempunyai kaedah OnreadyStatechange yang kita tidak benar -benar peduli, dan kemudian kaedah terbuka dan menghantar. Sangat bagus. Oleh itu, idea kami adalah untuk menampal kaedah hantar dan memberitahu ia tidak melakukan panggilan ke url tertentu. OK, ternyata anda tidak boleh mendapatkan URL sasaran dari objek itu sendiri. Alamak. Lalu apa yang harus kita lakukan? Kami meletakkannya pada objek. Mencari peluang pertama untuk mendapatkan URL, kita dapat melihat bahawa kaedah terbuka menerimanya sebagai parameter kedua. Untuk menjadikan URL tersedia dalam objek itu sendiri, mari kita mulakan dengan kaedah terbuka MP. seperti dahulu, kami menyimpan kaedah terbuka asal dalam pembolehubah untuk kegunaan kemudian. Kemudian kami mengatasi pelaksanaan asal dengan pelaksanaan tersuai. Oleh kerana kita boleh menggunakan JavaScript (bahasa dinamik), kita boleh membuat harta baru pada bila -bila masa dan namakannya, yang akan ditetapkan kepada nilai parameter yang diluluskan. Selain itu, kami memanggil kaedah terbuka asal tanpa melakukan sebarang operasi lain. mengkaji semula Ahli Parlimen Send kami, sudah jelas bagaimana untuk menyelesaikan pemeriksaan keadaan. Berikut adalah versi yang diubahsuai: Kesimpulan Apa yang kita lihat di sini adalah pengenalan ringkas tentang mengubah tingkah laku kod semasa runtime menggunakan patch monyet. Tetapi yang lebih penting, saya harap jawatan ini akan memberi anda idea bagaimana menangani patch monyet. Walaupun patch itu sendiri biasanya mudah, adalah penting untuk mempunyai idea bagaimana untuk menyesuaikan kod semasa runtime. Juga, saya harap tidak kira apa yang anda fikirkan patch monyet, anda mempunyai peluang untuk melihat keindahan menggunakan bahasa dinamik, yang membolehkan anda untuk mengubah secara dinamik walaupun pelaksanaan asli pada masa runtime. Walaupun konsep patch monyet dalam JavaScript dan Python adalah sama - tingkah laku mengubah atau memanjangkan objek - pelaksanaannya berbeza kerana perbezaan bahasa itu sendiri. Dalam JavaScript, patch monyet biasanya dilakukan dengan mengubah prototaip objek, sementara di Python, ia dilakukan dengan menambahkan atau mengubah kaedah kelas atau contoh. Fleksibiliti kedua -dua bahasa membolehkan penampalan monyet, tetapi teknik ini harus digunakan dengan berhati -hati untuk mengelakkan tingkah laku yang tidak dijangka. Patch monyet adalah alat yang berkuasa, tetapi ia bukan tanpa kontroversi. Walaupun ia dapat mengubahsuai atau memperluaskan ciri -ciri dengan cepat tanpa mengubah kod sumber asal, ia juga boleh membawa kepada tingkah laku dan konflik yang tidak dapat diramalkan, terutamanya apabila terlalu banyak atau tidak sesuai. Oleh itu, sering disyorkan untuk menggunakan patch monyet dengan berhati -hati dan tanggungjawab, dan sentiasa mempertimbangkan kesan yang berpotensi ke atas keseluruhan asas kod. Risiko utama patch monyet adalah bahawa ia boleh membawa kepada tingkah laku yang tidak dapat diramalkan dan konflik dalam kod. Kerana ia mengubah tingkah laku objek sedia ada, ia boleh memecahkan kod jika kaedah yang ditampal digunakan di tempat lain di pangkalan kod. Ia juga boleh menyebabkan kekeliruan di kalangan pemaju lain yang mungkin tidak menyedari pengubahsuaian. Oleh itu, adalah penting untuk merekodkan sebarang patch monyet dengan jelas dan komprehensif. Untuk membersihkan fungsi dalam JavaScript, anda boleh membuat pembalut di sekitar fungsi asal. Fungsi pembalut ini akan memanggil fungsi asal dan kemudian menambah atau mengubah suai tingkah laku yang diperlukan. Dengan cara ini, fungsi asal tetap tidak berubah dan tingkah laku tambahan jelas dipisahkan, menjadikan kod lebih mudah difahami dan dikekalkan. Ya, patch monyet boleh digunakan sebagai alat yang berguna untuk ujian dan debugging. Dengan mengubahsuai atau memperluaskan tingkah laku fungsi atau kaedah, anda boleh mensimulasikan senario yang berbeza, menyuntik kesilapan, atau menambah log untuk mengesan pelaksanaan kod anda. Walau bagaimanapun, adalah penting untuk menghapuskan atau mengasingkan patch ini dalam kod pengeluaran untuk mengelakkan sebarang kesan sampingan yang tidak dijangka. Dalam JavaScript, prototaip memainkan peranan penting dalam patch monyet. Oleh kerana JavaScript adalah bahasa berasaskan prototaip, setiap objek mempunyai prototaip yang mewarisi sifat dan kaedah daripadanya. Dengan mengubahsuai prototaip objek, anda boleh mengubah tingkah laku semua contoh objek itu. Ini adalah asas untuk patch monyet dalam JavaScript. Kesan patch monyet pada prestasi JavaScript biasanya kecil. Walau bagaimanapun, penggunaan tampalan monyet yang berlebihan atau tidak wajar boleh menyebabkan masalah prestasi. Sebagai contoh, jika anda sering menggunakan kaedah yang ditampal dalam kod anda, tingkah laku tambahan mungkin melambatkan pelaksanaan. Oleh itu, pastikan anda menggunakan patch monyet dengan berhati -hati dan memantau prestasi dengan kerap. Ya, patch monyet boleh digunakan untuk memperluaskan objek JavaScript terbina dalam. Dengan mengubahsuai prototaip objek terbina dalam, anda boleh menambah kaedah atau sifat baru yang akan tersedia untuk semua contoh objek. Walau bagaimanapun, ini perlu dilakukan dengan berhati -hati untuk mengelakkan konflik dengan versi masa depan JavaScript, yang mungkin memperkenalkan kaedah atau sifat yang sama. Terdapat beberapa alternatif untuk patch monyet dalam JavaScript. Cara yang sama adalah dengan menggunakan kombinasi, di mana anda membuat objek baru yang mengandungi objek asal dan menambah atau menimpa tingkah laku. Cara lain ialah menggunakan warisan, di mana anda membuat kelas baru yang mewarisi dari kelas asal dan menimpa kaedah. Kaedah ini boleh memberikan fleksibiliti yang sama kepada patch monyet, tetapi dengan enkapsulasi yang lebih baik dan kurang risiko konflik. yang pertama adalah kaedah yang dipanggil ToggleError, yang harus mengubah warna latar belakang elemen berdasarkan parameter Boolean
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
if(isError) {
obj.css("background-color", "darkgrey");
} else {
obj.css("background-color", "");
}
}</code>
Apabila membangunkan widget, gunakan log konsol untuk meminta pemaju untuk apa yang sedang dijalankan. Ini mungkin pendekatan yang baik semasa pembangunan, tetapi ia bukan pendekatan terbaik dalam penggunaan pengeluaran. Oleh itu, kita perlu mencari jalan untuk menghapuskan semua kenyataan debug ini.
Widget hebat, tetapi ia mempunyai tingkah laku yang pelik. Setiap kali skrip dimulakan, ia membuat permintaan kepada pelayan iklan yang pelik dan memaparkan kandungan kembung yang tidak perlu pada halaman kami.
<code class="language-javascript">FeedbackBox.prototype.init = function() {
// 我们想要跳过的广告服务器调用
$.ajax('vendor/service.json', {
method: 'GET'
}).then(function(data) {
console.log("FeedbackBox: AdServer contacted");
});
...
</code>
Nota: Kod demo menyerupai permintaan Ajax keluar untuk fail JSON di Plunker, tetapi saya harap anda memahami ini.
Kaedah liputan <code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
if(isError) {
obj.css("background-color", "darkgrey");
} else {
obj.css("background-color", "");
}
}</code>
<code class="language-javascript">FeedbackBox.prototype.init = function() {
// 我们想要跳过的广告服务器调用
$.ajax('vendor/service.json', {
method: 'GET'
}).then(function(data) {
console.log("FeedbackBox: AdServer contacted");
});
...
</code>
<code class="language-javascript">function FeedbackBox(elem, options) {
this.options = options;
this.element = elem;
this.isOpen = false;
}
FeedbackBox.prototype.toggleError = function(obj, isError) {
...
}</code>
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
if(isError) {
obj.css("background-color", "darkgrey");
} else {
obj.css("background-color", "");
}
}</code>
<code class="language-javascript">FeedbackBox.prototype.init = function() {
// 我们想要跳过的广告服务器调用
$.ajax('vendor/service.json', {
method: 'GET'
}).then(function(data) {
console.log("FeedbackBox: AdServer contacted");
});
...
</code>
<code class="language-javascript">function FeedbackBox(elem, options) {
this.options = options;
this.element = elem;
this.isOpen = false;
}
FeedbackBox.prototype.toggleError = function(obj, isError) {
...
}</code>
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
if(isError) {
obj.addClass("error");
} else {
obj.removeClass("error");
}
};</code>
<code class="language-javascript">var originalConsoleLog = console.log;
console.log = function(text) {
if (typeof text === "string" && text.indexOf("FeedbackBox:") === 0) {
return;
}
originalConsoleLog.apply(console, arguments);
}</code>
Soalan Lazim Mengenai Patch Monyet Praktikal (Soalan Lazim)
Patch monyet dalam JavaScript adalah teknik di mana tingkah laku objek terbina dalam atau pengguna diubahsuai, biasanya dengan menambah, mengubahsuai, atau mengubah prototaip objek. Ini adalah cara untuk memperluaskan atau mengubah tingkah laku kod tanpa mengubah kod sumber asal. Teknik ini boleh digunakan untuk melaksanakan pembaikan, meningkatkan fungsi sedia ada, dan juga untuk tujuan ujian dan debugging.
Apakah perbezaan antara patch monyet dalam JavaScript dan Python?
Adakah Monyet Patch dianggap sebagai amalan yang baik dalam JavaScript?
Apakah potensi risiko patch monyet?
Bagaimana untuk membersihkan fungsi dalam JavaScript?
Bolehkah patch monyet digunakan untuk ujian dan debug?
Apakah peranan yang dimainkan oleh prototaip dalam patch monyet dalam JavaScript?
Bagaimana Patch Monyet mempengaruhi prestasi dalam JavaScript?
Bolehkah patch monyet digunakan untuk memperluaskan objek JavaScript terbina dalam?
Apakah beberapa alternatif untuk patch monyet dalam JavaScript?
Atas ialah kandungan terperinci Penggunaan Pragmatik Monyet dalam JavaScript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!