Rumah >hujung hadapan web >tutorial js >Cepat faham Currying dalam JS dalam satu artikel
Artikel ini akan memberi anda pemahaman yang cepat tentang Currying dalam Javascript Ia mempunyai nilai rujukan tertentu.
Currying menukar fungsi berbilang parameter kepada fungsi unary (parameter tunggal). [Cadangan berkaitan: Tutorial pembelajaran javascript]
Fungsi kari menerima berbilang parameter pada satu masa. Jadi jika anda mempunyai
greet = (greeting, first, last) => `${greeting}, ${first} ${last}`; greet('Hello', 'Bruce', 'Wayne'); // Hello, Bruce Wayne
anda boleh menulisnya dalam borang ini
curriedGreet = curry(greet); curriedGreet('Hello')('Bruce')('Wayne'); // Hello, Bruce Wayne
Penggunaan "kari" yang betul adalah kerana beberapa fungsi curry
lebih fleksibel digunakan. Kari adalah hebat dalam teori, tetapi memanggil fungsi untuk setiap hujah dalam JavaScript boleh memenatkan.
Fungsi curry
Ramda membolehkan anda curriedGreet
memanggilnya seperti ini:
// greet requires 3 params: (greeting, first, last) // these all return a function looking for (first, last) curriedGreet('Hello'); curriedGreet('Hello')(); curriedGreet()('Hello')()(); // these all return a function looking for (last) curriedGreet('Hello')('Bruce'); curriedGreet('Hello', 'Bruce'); curriedGreet('Hello')()('Bruce')(); // these return a greeting, since all 3 params were honored curriedGreet('Hello')('Bruce')('Wayne'); curriedGreet('Hello', 'Bruce', 'Wayne'); curriedGreet('Hello', 'Bruce')()()('Wayne');
Perhatikan bahawa anda boleh memilih untuk memberikan berbilang parameter sekaligus . Pelaksanaan ini lebih berguna semasa menulis kod.
Seperti yang ditunjukkan di atas, anda boleh memanggil fungsi ini selama-lamanya tanpa argumen dan ia akan sentiasa mengembalikan fungsi yang memerlukan argumen yang tinggal.
const curry = (f, arr = []) => (...args) => ((a) => (a.length === f.length ? f(...a) : curry(f, a)))([...arr, ...args]);
Mari kita bina semula dan menghargainya bersama-sama.
Saya turut menambah beberapa kenyataan dalam debugger
Alat Pembangun Chrome untuk menyemaknya.
curry = (originalFunction, initialParams = []) => { debugger; return (...nextParams) => { debugger; const curriedFunction = (params) => { debugger; if (params.length === originalFunction.length) { return originalFunction(...params); } return curry(originalFunction, params); }; return curriedFunction([...initialParams, ...nextParams]); }; };
Tampal greet
dan curry
ke dalam konsol anda. Kemudian masukkan curriedGreet = curry(greet)
dan mula menjadi gila.
Semak dua parameter yang kita lihat, originalFunction
dan greet
LalaiinitialParams
ialah tatasusunan kosong kerana kami tidak menyediakannya. Bergerak ke titik putus seterusnya dan oh tunggu...itu sahaja.
Ya! curry(greet)
Hanya kembalikan fungsi baharu yang memerlukan lebih daripada 3 argumen. Taip curriedGreet
dalam konsol untuk melihat perkara yang saya perkatakan.
Apabila anda selesai bermain dengan ini, mari kita menjadi lebih gila dan lakukan sayHello = curriedGreet('Hello')
.
Sebelum meneruskan, masukkan originalFunction
dan dalam konsol. initialParams
Sila ambil perhatian bahawa walaupun kami berada dalam fungsi serba baharu, kami masih mempunyai akses kepada dua parameter ini? Ini kerana fungsi yang dikembalikan daripada fungsi induk berkongsi skop fungsi induknya.
Selepas fungsi ibu bapa diluluskan, mereka menyerahkan parameter kepada anak. Macam warisan dalam kehidupan sebenar.
curry
pada mulanya memberikan originalFunction
, initialParams
kemudian mengembalikan fungsi "kanak-kanak". Kedua-dua pembolehubah ini belum dilupuskan lagi, kerana mungkin kanak-kanak memerlukannya. Jika dia tidak, maka julat akan dikosongkan, kerana apabila tiada sesiapa yang menyebut anda, ketika itulah anda benar-benar mati.
Semak nextParams
dan lihat ia ['Hello']
... ...susunan ? Tetapi saya fikir kami berkata curriedGreet(‘Hello’)
, bukan curriedGreet(['Hello'])
!
betul: kami memanggil curriedGreet
dengan 'Hello'
, tetapi terima kasih kepada sintaks rehat , kami menjadi 'Hello'
dengan ['Hello']
.
curry
ialah fungsi umum yang boleh menyediakan 1, 10 atau 10,000,000 hujah, jadi ia memerlukan cara untuk merujuk semua hujah. Gunakan sintaks seperti rehat untuk menangkap setiap hujah dalam tatasusunan, menjadikan tugas curry
' lebih mudah.
Mari beralih ke pernyataan debugger
seterusnya.
您可能已经注意到第 12 行实际上在debugger
第 6 行的语句之前运行。如果不是,请仔细查看。我们的程序在第 5 行定义了一个调用函数curriedFunction
,在第 12 行使用它,然后我们debugger
在第 6 行点击了该语句。curriedFunction
调用的是什么?
[...initialParams, ...nextParams];
呸呸呸。查看params
第 5 行,您会看到['Hello']
. 两者initialParams
和都是数组,所以我们使用方便的扩展运算符nextParams
将它们展平并组合成一个数组。
这就是好事发生的地方。
第 7 行说“如果params
和originalFunction
长度相同,请greet
使用我们的参数调用,我们就完成了。” 这使我想起…
这就是curry
它的魔力!这就是它决定是否要求更多参数的方式。
在 JavaScript 中,函数的 .length
属性告诉你它需要多少个参数。
greet.length; // 3 iTakeOneParam = (a) => {}; iTakeTwoParams = (a, b) => {}; iTakeOneParam.length; // 1 iTakeTwoParams.length; // 2复制代码
如果我们提供的和预期的参数匹配,我们很好,只需将它们交给原始函数并完成工作!
但是在我们的例子中,参数和函数长度是不一样的。我们只提供了‘Hello’
,所以params.length
是 1,并且originalFunction.length
是 3 因为greet
需要 3 个参数:greeting, first, last
。
好吧,由于该if
语句的计算结果为false
,代码将跳到第 10 行并重新调用我们的主curry
函数。它重新接收greet
,这一次,'Hello'
并重新开始疯狂。
这就是递归,我的朋友们。
curry
本质上是一个无限循环的自调用,参数饥渴的函数,直到他们的客人满了才会休息。热情好客。
与以前相同initialParams
的参数,除了['Hello']
这次。再次跳过以退出循环。在控制台中输入我们的新变量,sayHello
. 这是另一个函数,仍然期待更多参数,但我们正在变得更加温暖......
让我们把火调大sayHelloToJohn = sayHello('John')
。
我们又在第 4 行了,而且nextParams
是['John']
。跳到第 6 行的下一个调试器并检查params
:它是['Hello', 'John']
!?
因为请记住,第 12 行说“嘿curriedFunction
,他'Hello'
上次和‘John’
这次都给了我。把他们两个都带进这个阵法[...initialParams, ...nextParams]
。”
现在curriedFunction
再次将length
这些params
与进行比较originalFunction
,因为2 我们移动到第 10 行并<code>curry
再次调用!当然,我们传递greet
了我们的 2 个参数,['Hello', 'John']
我们已经很接近了,让我们完成这一切,并得到完整的问候!
sayHelloToJohnDoe = sayHelloToJohn('Doe')
我想我们知道接下来会发生什么。
greet
得到他的参数,curry
停止循环,我们收到了我们的问候:Hello, John Doe
.
多玩一些这个功能。尝试一次提供多个参数或不提供参数,随心所欲地疯狂。curry
查看在返回预期输出之前必须递归多少次。
curriedGreet('Hello', 'John', 'Doe'); curriedGreet('Hello', 'John')('Doe'); curriedGreet()()('Hello')()('John')()()()()('Doe');
【相关视频教程推荐:web前端 】
Atas ialah kandungan terperinci Cepat faham Currying dalam JS dalam satu artikel. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!