Asal kari dan nama matematikawan Haskell Curry (bahasa pemrograman Haskell juga dinamai menurut namanya).
Currying juga biasanya disebut evaluasi parsial. Artinya adalah meneruskan parameter ke fungsi langkah demi langkah. Setelah setiap parameter dilewati, sebagian terapkan parameter, dan mengembalikan fungsi yang lebih spesifik untuk menerima parameter yang tersisa. Beberapa lapisan fungsi parameter parsial tersebut dapat bersarang di tengah sampai hasil akhir dikembalikan.
Oleh karena itu, proses kari adalah proses parameter yang secara bertahap melewati, secara bertahap mempersempit ruang lingkup penerapan fungsi, dan secara bertahap memecahkannya.
Kari fungsi jumlah
Mengikuti evaluasi langkah demi langkah, mari kita lihat contoh sederhana
var concat3words = fungsi (a, b, c) {return a+b+c; }; var concat3wordscurrying = function (a) {return function (b) {return function (c) {return a+b+c; }; }; }; console.log (concat3words ("foo", "bar", "baza")); // foo bar baza console.log (concat3wordscurrying ("foo")); // [function] console.log (concat3wordscurrying ("foo") ("bar") ("baza"))); // foo bar bazaSeperti yang Anda lihat, concat3wordscurrying ("foo") adalah fungsi, setiap panggilan mengembalikan fungsi baru, yang menerima panggilan lain, dan kemudian mengembalikan fungsi baru sampai hasilnya akhirnya dikembalikan, dan distribusinya diselesaikan, dan berkembang berlapis -lapis. (PS: Karakteristik penutupan dimanfaatkan di sini)
Jadi sekarang kita melangkah lebih jauh. Jika kita membutuhkan lebih dari 3 parameter untuk dilewati, kita dapat melewati parameter sebanyak mungkin dan mengeluarkan hasilnya ketika parameter tidak dilewati?
Pertama, mari kita memiliki implementasi normal:
var add = function (item) {return items.reduce (function (a, b) {return a+b}); }; console.log (add ([1,2,3,4]));Tetapi jika Anda meminta untuk melipatgandakan setiap angka dengan 10 dan kemudian menambahkannya, maka:
var add = function (item, multi) {return items.map (function (item) {return item*multi;}). redebelor (function (a, b) {return a + b}); }; console.log (add ([1, 2, 3, 4], 10));Untungnya, ada peta dan mengurangi fungsi. Jika kita mengikuti pola ini, kita perlu menambahkan 1 ke setiap item dan merangkumnya, maka kita perlu mengganti fungsi di peta.
Mari kita lihat implementasi kariisasi:
var adder = function () {var _args = []; return function () {if (arguments.length === 0) {return _args.reduce (function (a, b) {return a + b;}); } [] .push.Apply (_Args, [] .slice.call (argumen)); pengembalian argumen.callee; }}; var sum = adder (); console.log (sum); // jumlah fungsi (100.200) (300); // Format panggilan fleksibel, satu atau lebih parameter dapat dimasukkan pada satu waktu, dan mendukung panggilan rantai untuk menyimpulkan (400); console.log (sum ()); // 1000 (total perhitungan)Adder di atas adalah fungsi berbentuk kari, yang mengembalikan fungsi baru, dan fungsi baru dapat menerima parameter baru dalam batch, menunda sampai perhitungan terakhir.
Fungsi kari umum
Kari yang lebih khas akan merangkum perhitungan terakhir ke dalam fungsi, dan kemudian meneruskan fungsi ini sebagai parameter ke dalam fungsi kari, yang jelas dan fleksibel.
Misalnya, kalikan setiap istilah dengan 10, kita dapat melewati fungsi pemrosesan sebagai parameter:
var currying = function (fn) {var _args = []; return function () {if (arguments.length === 0) {return fn.Apply (this, _args); } Array.prototype.push.apply (_args, [] .slice.call (argumen)); pengembalian argumen.callee; }}; var multi = fungsi () {var total = 0; untuk (var i = 0, c; c = argumen [i ++];) {total+= c; } Total pengembalian; }; var sum = kari (multi); jumlah (100.200) (300); jumlah (400); console.log (sum ()); // 1000 (hanya dihitung saat panggilan kosong)Dengan cara ini, sum = kari (multi), panggilannya sangat jelas, dan efek penggunaannya juga brilian. Misalnya, untuk mengakumulasi beberapa nilai, Anda dapat menggunakan beberapa nilai sebagai jumlah parameter (1,2,3), atau panggilan rantai dukungan, jumlah (1) (2) (3)
Fondasi kari
Kode di atas sebenarnya adalah fungsi orde tinggi. Fungsi tingkat tinggi mengacu pada fungsi yang mengoperasikan fungsi. Ini menerima satu atau lebih fungsi sebagai parameter dan mengembalikan fungsi baru. Selain itu, karakteristik penutupan juga diandalkan untuk menyimpan parameter yang dimasukkan dalam proses perantara. Sekarang:
Fungsi dapat dilewatkan sebagai parameter
Fungsi dapat digunakan sebagai nilai pengembalian fungsi
Penutup
Peran Curryculation
Perhitungan tunda. Contoh di atas relatif rendah.
Parameter multiplexing. Ketika fungsi yang sama disebut beberapa kali dan parameter yang dilewati sebagian besar sama, maka fungsinya mungkin kandidat yang baik untuk kari.
Buat fungsi secara dinamis. Ini dapat dihasilkan secara dinamis setelah hasil perhitungan parsial, atas dasar ini, fungsi baru dihasilkan secara dinamis untuk memproses bisnis berikutnya, sehingga menghilangkan perhitungan yang berulang. Atau Anda dapat secara dinamis membuat fungsi baru dengan menerapkan bagian dari subset parameter untuk diteruskan ke fungsi panggilan, yang menghemat parameter yang dilewati berulang kali (tidak harus setiap kali di masa depan). Misalnya, metode tambahan untuk browser acara untuk menambahkan acara:
var addevent = function (el, type, fn, capture) {if (window.addeventListener) {el.addeventListener (type, function (e) {fn.call (el, e);}, capture); } else if (window.attachevent) {el.attachevent ("on" + type, function (e) {fn.call (el, e);}); }};Setiap kali Anda menambahkan acara, Anda harus mengeksekusi jika ... lain .... pada kenyataannya, di browser, Anda hanya perlu membuat keputusan sekali. Anda dapat secara dinamis menghasilkan fungsi baru berdasarkan hasil setelah penilaian, dan tidak perlu menghitung ulang di masa depan.
var addevent = (function () {if (window.addeventListener) {return function (el, stype, fn, capture) {el.addeventlistener (stype, function (e) {fn.call (el, e);}, (capture));}; {window.call {eL);}, capture));};} lain if (window.attachevent), {capture));}; {window.attachevent), {capture)); el.attachevent ("on" + stype, function (e) {fn.call (el, e);});Contoh ini, setelah penilaian pertama jika ... lain ..., bagian dari perhitungan selesai, dan fungsi baru dibuat secara dinamis untuk memproses parameter yang dilewati nanti. Ini adalah kurrylasi yang khas.
Metode function.prototype.bind juga merupakan aplikasi kari
Berbeda dengan metode panggilan/terapkan yang dieksekusi secara langsung, metode BIND menetapkan parameter pertama ke konteks eksekusi fungsi, dan parameter lain diteruskan ke metode panggilan pada gilirannya (tubuh fungsi itu sendiri tidak dieksekusi, yang dapat dianggap sebagai eksekusi tertunda), dan secara dinamis membuat dan mengembalikan fungsi baru, yang sesuai dengan karakteristik currying.
var foo = {x: 888}; var bar = function () {console.log (this.x); } .bind (foo); // bind bar (); // 888Di bawah ini adalah simulasi fungsi BIND. TestBind membuat dan mengembalikan fungsi baru. Dalam fungsi baru, fungsi yang benar -benar ingin menjalankan bisnis terikat pada konteks yang disahkan dalam parameter aktual, dan eksekusi tertunda.
Function.prototype.testbind = function (scope) {var fn = this; //// ini menunjuk ke fungsi yang memanggil metode testBind, return function () {return fn.Apply (scope); }}; var testBindBar = bar.testbind (foo); // Bind foo untuk menunda eksekusi console.log (testBindBar); // fungsi (lihat, setelah mengikat, mengembalikan fungsi baru yang menunda eksekusi) testBindBar (); // 888Di sini kita harus memperhatikan pemahaman ini dalam prototipe.
Artikel di atas analisis mendalam dari fungsi-fungsi yang dikurangi dalam javascript adalah semua konten yang saya bagikan dengan Anda. Saya harap Anda dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.