Rumah >hujung hadapan web >tutorial js >Penggunaan Pragmatik Monyet dalam JavaScript

Penggunaan Pragmatik Monyet dalam JavaScript

William Shakespeare
William Shakespeareasal
2025-02-17 12:52:10448semak imbas

Pragmatic Uses of Monkey Patching in JavaScript

mata teras

    Patch Monyet (MP) dalam JavaScript adalah teknologi yang membolehkan pengaturcara menimpa, memperluaskan, atau menindas tingkah laku lalai segmen kod tanpa mengubah kod sumber asalnya.
  • Walaupun MP sering dianggap sebagai amalan yang buruk, ia boleh digunakan sebagai alat yang berguna untuk mengubah suai kod pihak ketiga untuk memenuhi keperluan khusus, terutamanya jika kod sumber asal tidak dapat diubah.
  • MP boleh digunakan untuk menimpa fungsi sedia ada dengan tingkah laku tersuai, meningkatkan kaedah dengan menambahkan tingkah laku tersuai sebelum atau selepas kod asal, atau memintas panggilan AJAX untuk mengubah suai tingkah laku mereka.
  • MP hendaklah digunakan dengan berhati -hati, kerana ia boleh menyebabkan tingkah laku dan konflik yang tidak dapat diramalkan dalam kod, terutamanya jika kaedah yang ditampal digunakan di tempat lain di pangkalan kod.
  • Walaupun risiko yang berpotensi, MP masih boleh menjadi alat yang berkuasa untuk menguji, menyahpepijat, dan melaksanakan pembaikan, menonjolkan fleksibiliti dan sifat dinamik JavaScript sebagai bahasa pengaturcaraan.

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! Pragmatic Uses of Monkey Patching in JavaScript

Adakah anda pernah menggunakan kod pihak ketiga yang berfungsi dengan baik kecuali satu soalan kecil yang mendorong anda gila? Kenapa Pencipta lupa untuk memadamkan log konsol yang menjengkelkan? Bukankah itu bagus jika panggilan API itu dapat melakukan satu perkara lagi? Jika ya, maka anda tahu bahawa mempunyai penyelenggara melaksanakan perubahan anda boleh menjadi sukar (atau mustahil). Tetapi, bagaimana pula dengan menukar kod itu sendiri? Bagaimana jika anda tidak mempunyai kod sumber dan tidak mahu menjadi tuan rumah sendiri? Selamat datang ke Perjalanan Dunia JavaScript Monkey Patch!

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.

Kod sumber telah diubahsuai untuk memasukkan kes penggunaan untuk digunakan sebagai sasaran MP. Matlamatnya merujuk kepada fungsi, ciri atau penggunaan tahap minimum yang akan kami tambahkan.

Pragmatic Uses of Monkey Patching in JavaScript 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.

sasaran patch monyet

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

yang pertama adalah kaedah yang dipanggil ToggleError, yang harus mengubah warna latar belakang elemen berdasarkan parameter Boolean

seperti yang anda lihat, ia menetapkan harta warna latar belakang melalui kaedah jQuery CSS. Ini adalah masalah kerana kita mahu menentukannya melalui peraturan stylesheet.
<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.css("background-color", "darkgrey");
  } else {
    obj.css("background-color", "");
  }
}</code>

log konsol Nevil

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.

blok panggilan pelayan iklan

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

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.

<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.css("background-color", "darkgrey");
  } else {
    obj.css("background-color", "");
  }
}</code>

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.

<code class="language-javascript">FeedbackBox.prototype.init = function() {
  // 我们想要跳过的广告服务器调用
  $.ajax('vendor/service.json', {
    method: 'GET'
  }).then(function(data) {
    console.log("FeedbackBox: AdServer contacted");
  });

  ...
</code>

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.

<code class="language-javascript">function FeedbackBox(elem, options) {
  this.options = options;  
  this.element = elem;  
  this.isOpen = false;
}

FeedbackBox.prototype.toggleError = function(obj, isError) {
  ...
}</code>

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:

<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.css("background-color", "darkgrey");
  } else {
    obj.css("background-color", "");
  }
}</code>

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:

<code class="language-javascript">FeedbackBox.prototype.init = function() {
  // 我们想要跳过的广告服务器调用
  $.ajax('vendor/service.json', {
    method: 'GET'
  }).then(function(data) {
    console.log("FeedbackBox: AdServer contacted");
  });

  ...
</code>

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.

<code class="language-javascript">function FeedbackBox(elem, options) {
  this.options = options;  
  this.element = elem;  
  this.isOpen = false;
}

FeedbackBox.prototype.toggleError = function(obj, isError) {
  ...
}</code>

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.

<code class="language-javascript">FeedbackBox.prototype.toggleError = function(obj, isError) {
  if(isError) {
    obj.addClass("error");
  } else {
    obj.removeClass("error");
  }
};</code>

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:

<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>

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.

Soalan Lazim Mengenai Patch Monyet Praktikal (Soalan Lazim)

Apakah konsep Patch Monyet dalam JavaScript?

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?

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.

Adakah Monyet Patch dianggap sebagai amalan yang baik dalam JavaScript?

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.

Apakah potensi risiko patch monyet?

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.

Bagaimana untuk membersihkan fungsi dalam JavaScript?

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.

Bolehkah patch monyet digunakan untuk ujian dan debug?

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.

Apakah peranan yang dimainkan oleh prototaip dalam patch monyet dalam JavaScript?

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.

Bagaimana Patch Monyet mempengaruhi prestasi 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.

Bolehkah patch monyet digunakan untuk memperluaskan objek JavaScript terbina dalam?

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.

Apakah beberapa alternatif untuk patch monyet dalam JavaScript?

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.

Atas ialah kandungan terperinci Penggunaan Pragmatik Monyet dalam JavaScript. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn