Rumah > hujung hadapan web > tutorial js > Rekursi dalam javascript berfungsi

Rekursi dalam javascript berfungsi

Joseph Gordon-Levitt
Lepaskan: 2025-02-19 10:22:09
asal
339 orang telah melayarinya

Recursion in Functional JavaScript

Anda mungkin pernah mendengar fungsi rekursif dalam JavaScript, dan juga cuba menulis beberapa. Tetapi anda mungkin tidak melihat banyak contoh rekursi yang sebenarnya berfungsi. Sebenarnya, selain kekhususan pendekatan ini, anda mungkin tidak mempertimbangkan kapan dan di mana rekursi berguna, atau betapa berbahayanya jika digunakan secara tidak wajar.

mata utama

    rekursi adalah kaedah JavaScript yang membolehkan fungsi itu berulang kali memanggil dirinya sehingga hasilnya dicapai. Ia amat berguna untuk masalah yang melibatkan cawangan berulang, seperti matematik fraktal, menyusun atau melintasi struktur data kompleks atau tidak linear.
  • Walaupun rekursi boleh membuat kod lebih ringkas dan mudah difahami, jika digunakan secara tidak wajar, ia boleh berbahaya kerana risiko melebihi kapasiti memori enjin. Ini kerana fungsi rekursif JavaScript perlu menjejaki tempat mereka dipanggil dari setiap masa supaya mereka dapat terus melaksanakan di tempat yang betul.
  • Dalam banyak bahasa pengaturcaraan berfungsi, teknik yang dipanggil pengoptimuman panggilan ekor digunakan untuk menguruskan rekursi. Ini membolehkan setiap gelung berterusan dalam fungsi rekursif berlaku dengan serta -merta, dan bukannya menumpuk dalam ingatan. Walau bagaimanapun, kebanyakan penyusun JavaScript tidak dioptimumkan untuk ini lagi.
  • Fungsi Bounce Custom boleh dibina untuk menguruskan pelaksanaan rekursif secara beransur -ansur, meninggalkan hanya satu operasi pada timbunan pada satu masa. Ini dapat membantu mengelakkan membuat operasi timbunan yang mendalam menunggu untuk dilakukan, tetapi biasanya dengan mengorbankan prestasi dan kebolehbacaan.

Tujuan rekursi

rekursi adalah teknik yang meleleh melalui operasi dengan mempunyai fungsi panggilan sendiri berulang kali sehingga hasilnya diperolehi. Kebanyakan gelung boleh ditulis semula dalam gaya rekursif, dan dalam beberapa bahasa pengaturcaraan berfungsi, kaedah gelung ini adalah lalai.

Walau bagaimanapun, sementara gaya pengaturcaraan fungsional JavaScript menyokong fungsi rekursif, kita perlu menyedari bahawa kebanyakan penyusun JavaScript tidak dioptimumkan pada masa ini dengan selamat.

rekursi lebih baik digunakan apabila anda perlu berulang kali memanggil fungsi yang sama dengan parameter yang berbeza dalam gelung. Walaupun ia boleh digunakan dalam banyak kes, ia adalah yang paling berkesan dalam menyelesaikan masalah yang melibatkan cawangan berulang seperti matematik fraktal, menyusun atau melintasi nod struktur data kompleks atau tidak linear.

Salah satu sebab mengapa rekursi disukai dalam bahasa pengaturcaraan berfungsi ialah ia membolehkan kod bangunan yang tidak memerlukan penggunaan pembolehubah tempatan untuk menetapkan dan mengekalkan keadaan. Fungsi rekursif juga mudah diuji kerana mereka mudah ditulis dengan cara yang murni, mempunyai nilai pulangan yang spesifik dan konsisten untuk sebarang input yang diberikan dan tidak mempunyai kesan sampingan pada keadaan pemboleh ubah luaran.

Cycle

Contoh fungsi klasik yang rekursi boleh digunakan adalah faktorial. Ini adalah fungsi yang mengembalikan hasil nombor berulang kali didarabkan oleh setiap integer sebelumnya, sepanjang jalan ke 1.

Contohnya, faktorial 3 ialah:

Faktorial

6 adalah:

<code>3 × 2 × 1 = 6</code>
Salin selepas log masuk

Anda dapat melihat seberapa cepat hasil ini semakin besar. Anda juga boleh melihat kami mengulangi tingkah laku yang sama berulang kali. Kami mengambil hasil operasi pendaraban dan membiaknya dengan nilai kedua kepada tolak 1. Kemudian kita melakukan ini lagi dan lagi sehingga kita mencapai 1.

menggunakan gelung untuk, tidak sukar untuk membuat fungsi yang berulang untuk melakukan ini sehingga hasil yang betul dikembalikan:

<code>6 × 5 × 4 × 3 × 2 × 1 = 720</code>
Salin selepas log masuk

Ini berfungsi, tetapi dari sudut pandangan pengaturcaraan berfungsi, ia tidak elegan. Untuk menyokong gelung untuk dan kemudian mengembalikan hasilnya, kami perlu menggunakan beberapa pembolehubah tempatan yang mengekalkan dan menjejaki negeri. Bukankah lebih ringkas jika kita boleh membuang gelung untuk dan mengamalkan kaedah JavaScript yang lebih berfungsi?

rekursi

kita tahu bahawa JavaScript membolehkan kita menulis fungsi yang mengambil fungsi sebagai parameter. Jadi bagaimana jika kita mahu menggunakan fungsi sebenar kita menulis dan melaksanakannya dalam konteks di mana kita menjalankannya?

Adakah ini mungkin? Pasti! Sebagai contoh, pertimbangkan seperti gelung semasa:

var factor = function(number) {
  var result = 1;
  var count;
  for (count = number; count > 1; count--) {
    result *= count;
  }
  return result;
};
console.log(factor(6));
// 720
Salin selepas log masuk

Selepas ini dilakukan, nilai kaunter telah berubah, tetapi gelung telah menyelesaikan tugasnya mencetak setiap nilai, ketika kami perlahan -lahan mengekstrak negara daripadanya.

versi rekursif gelung yang sama mungkin kelihatan seperti ini:

var counter = 10;
while(counter > 0) {
    console.log(counter--);
}
Salin selepas log masuk

Adakah anda melihat bagaimana kita memanggil fungsi undur secara langsung dalam definisi fungsi undur? JavaScript mengendalikannya seperti bos dan hanya melakukan apa yang anda mahu lakukan. Setiap undur masa dilaksanakan, trek JavaScript di mana ia dipanggil, dan kemudian kembali ke timbunan fungsi panggilan sehingga selesai. Fungsi kami juga mengelakkan mengubah keadaan mana -mana pembolehubah, tetapi masih menggunakan nilai yang diluluskan untuk mengawal rekursi.

Kembali ke kes faktorial kami, kami boleh menulis semula fungsi sebelumnya seperti ini untuk menggunakan rekursi:

var countdown = function(value) {
    if (value > 0) {
        console.log(value);
        return countdown(value - 1);
    } else {
        return value;
    }
};
countdown(10);
Salin selepas log masuk

Kod penulisan dengan cara ini membolehkan kita menerangkan keseluruhan proses dengan cara tanpa statistik tanpa sebarang kesan sampingan. Ia juga perlu diperhatikan bahawa kita mula -mula menguji nilai parameter yang diluluskan kepada fungsi dan kemudian melakukan apa -apa pengiraan. Kami mahu apa -apa fungsi yang akan memanggil dirinya untuk keluar dengan cepat dan bersih apabila ia mencapai penamatannya. Untuk faktorial yang dikira dengan cara ini, apabila nombor masuk adalah sifar atau negatif, keadaan penamatan dicapai (kita juga boleh menguji nilai negatif dan mengembalikan mesej yang berbeza jika kita mahu).

pengoptimuman panggilan ekor

Salah satu masalah dengan pelaksanaan JavaScript kontemporari adalah bahawa mereka tidak mempunyai cara standard untuk mencegah fungsi rekursif daripada menyusun ingatan diri mereka yang tak terhingga dan memakan sehingga mereka melebihi kapasiti enjin. Fungsi rekursif JavaScript perlu menjejaki tempat mereka dipanggil dari setiap masa supaya mereka dapat terus melaksanakan di tempat yang betul.

Dalam banyak bahasa pengaturcaraan berfungsi seperti Haskell dan Skim, ini diuruskan menggunakan teknik yang dipanggil Pengoptimuman Call Tail. Menggunakan pengoptimuman panggilan ekor, setiap gelung berterusan dalam fungsi rekursif akan berlaku dengan serta -merta, dan bukannya menumpuk dalam ingatan.

Dalam teori, pengoptimuman panggilan ekor adalah sebahagian daripada standard ECMAScript 6 (versi seterusnya JavaScript semasa), tetapi kebanyakan platform belum melaksanakannya sepenuhnya.

Fungsi Bounce

Jika perlu, ada cara untuk memaksa JavaScript untuk melaksanakan fungsi rekursif dengan cara yang selamat. Sebagai contoh, fungsi lantunan tersuai boleh dibina untuk mengurus pelaksanaan rekursif secara beransur -ansur, meninggalkan hanya satu operasi pada timbunan pada satu masa. Fungsi lantunan yang digunakan dengan cara ini dapat memanfaatkan keupayaan JavaScript untuk mengikat fungsi ke konteks tertentu untuk melantun fungsi rekursif kembali kepada dirinya sendiri, membina hasil satu demi satu sehingga gelung selesai. Ini akan mengelakkan membuat operasi timbunan yang mendalam menunggu pelaksanaan.

Malah, menggunakan fungsi melantun sering mengurangkan prestasi untuk keselamatan. Selain itu, kebanyakan keanggunan dan kebolehbacaan yang kita dapat dengan menulis fungsi secara rekursif hilang dalam konvolusi kod yang diperlukan untuk membuat pendekatan ini berfungsi di JavaScript.

Jika anda ingin tahu, saya menggalakkan anda membaca lebih lanjut mengenai konsep ini dan berkongsi pendapat anda dalam perbincangan di bawah. Anda boleh memulakan dengan topik pendek di StackOverflow dan meneroka beberapa artikel oleh Don Taylor dan Mark McDonnell yang lebih mendalam ke dalam kebaikan dan keburukan fungsi memantul dalam JavaScript.

kita belum pada ketika itu

rekursi adalah teknik yang kuat yang bernilai mengetahui. Dalam banyak kes, rekursi adalah cara yang paling mudah untuk menyelesaikan masalah yang rumit. Walau bagaimanapun, sebelum ECMAScript 6 melaksanakan sepenuhnya dengan pengoptimuman panggilan ekor di mana kita memerlukannya, kita perlu berhati -hati tentang bagaimana dan di mana rekursif digunakan.

Soalan Lazim Mengenai Rekursi dalam JavaScript berfungsi (Soalan Lazim)

Apakah keadaan asas dalam rekursi? Mengapa penting?

Keadaan asas dalam rekursi adalah keadaan yang menghalang fungsi daripada memanggil dirinya tak terhingga. Ia adalah penting kerana tanpa itu, fungsi rekursif akan memanggil dirinya secara tak terhingga, menyebabkan kesilapan limpahan timbunan. Keadaan asas biasanya adalah syarat bahawa fungsi memeriksa sebelum membuat panggilan rekursif. Jika keadaan ini dipenuhi, fungsi ini mengembalikan nilai dan berhenti memanggilnya sendiri.

Bagaimana rekursi berfungsi dalam JavaScript?

Dalam JavaScript, rekursi berfungsi dengan memanggil fungsi itu sendiri sehingga keadaan asas dicapai. Fungsi ini dibahagikan kepada kes asas dan kes rekursif. Kes asas mengembalikan nilai tanpa memanggil fungsi itu lagi, sementara kes rekursif memanggil fungsi itu lagi dengan parameter yang berbeza. Fungsi ini terus memanggil sendiri sehingga kes asas dicapai, di mana ia mula mengembalikan nilai.

Apakah rekursi ekor dalam JavaScript?

rekursi ekor adalah jenis rekursi khas, di mana panggilan rekursif adalah operasi terakhir dalam fungsi. Ini penting kerana ia membolehkan pengoptimuman enjin JavaScript untuk berulang, menggunakan teknik yang dipanggil pengoptimuman panggilan ekor. Ini dapat mengurangkan jumlah memori yang digunakan oleh fungsi, yang membolehkannya mengendalikan input yang lebih besar.

Apakah kelebihan dan kekurangan menggunakan rekursi dalam JavaScript?

rekursi boleh menjadikan kod lebih ringkas dan mudah difahami dengan memecahkan masalah yang kompleks ke dalam masalah yang lebih mudah. Ia amat berguna untuk tugas -tugas seperti melintasi struktur data pokok. Walau bagaimanapun, rekursi juga mungkin kurang cekap daripada penyelesaian berulang, dan jika dilaksanakan dengan tidak betul, ia boleh menyebabkan ralat limpahan timbunan.

Bagaimana untuk mengelakkan kesilapan limpahan timbunan dalam fungsi rekursif?

Apabila fungsi rekursif memanggil dirinya terlalu banyak dan mengisi timbunan panggilan, ralat limpahan timbunan akan berlaku. Untuk mengelakkan ini, pastikan fungsi rekursif anda mempunyai kes asas yang akhirnya akan dicapai. Juga, pertimbangkan untuk menggunakan rekursi ekor, yang enjin JavaScript boleh mengoptimumkan untuk menggunakan memori yang kurang.

Bagaimana rekursi digunakan dalam pengaturcaraan berfungsi?

Dalam pengaturcaraan berfungsi, rekursi sering digunakan sebagai pengganti gelung. Oleh kerana pengaturcaraan berfungsi tidak menggalakkan penggunaan keadaan berubah -ubah, rekursi boleh digunakan untuk melakukan operasi berulang tanpa mengubah mana -mana negeri.

Bolehkah semua fungsi rekursif ditukar kepada fungsi berulang?

Ya, dalam teori, semua fungsi rekursif boleh ditukar menjadi fungsi berulang. Walau bagaimanapun, versi berulang boleh menjadi lebih kompleks dan sukar difahami, terutamanya untuk fungsi yang melibatkan traversals pokok atau graf kompleks.

Apakah rekursi bersama dalam JavaScript?

rekursi bersama merujuk kepada dua atau lebih fungsi yang dipanggil antara satu sama lain dalam gelung. Ini mungkin teknik yang kuat untuk menyelesaikan beberapa jenis masalah, tetapi mungkin juga lebih sukar untuk difahami dan debug daripada rekursi mudah.

Bagaimana cara debug fungsi rekursif dalam JavaScript?

Menghancurkan fungsi rekursif boleh mencabar kerana panggilan fungsi berulang. Walau bagaimanapun, ia mungkin membantu mencetak parameter fungsi dan mengembalikan nilai pada setiap langkah menggunakan pernyataan Console.log. Di samping itu, sangat berguna untuk menggunakan alat debugger yang membolehkan anda melakukan fungsi panggilan langkah demi langkah.

Adakah terdapat pertimbangan prestasi semasa menggunakan rekursi?

Ya, fungsi rekursif mungkin tidak begitu efisien sebagai rakan berulangnya kerana overhead panggilan fungsi berulang. Sekiranya mereka memanggil diri mereka terlalu banyak, mereka juga boleh menyebabkan kesilapan limpahan timbunan. Walau bagaimanapun, dalam banyak kes, kebolehbacaan dan kesederhanaan penyelesaian rekursif boleh melebihi pertimbangan prestasi ini.

Atas ialah kandungan terperinci Rekursi dalam javascript berfungsi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan