Currying是一个来自lambda calculus的概念,但不要让它吓到你,它的实现非常简单。
Currying是一个函数,它一次接受一个参数,并返回一个期待下一个参数的新函数。它是一种函数的转换,将一个函数从可调用的f(a, b, c)转换为可调用的f(a)(b)(c)。
在这篇文章中,我们将探讨什么是Javascript中的currying,为什么以及在什么地方应该使用currying,以及如何通过代码实例实现它。
什么是JavaScript中的currying?
Currying简单地说,就是对有多个参数的函数进行评估,并将其分解为一连串有单个参数的函数。
换句话说,Currying是指一个函数--而不是一次性接受所有的参数--接受第一个参数并返回一个新的函数,后者接受第二个参数并返回一个新的函数,后者接受第三个参数,等等,直到所有参数都完成。
为什么我应该使用咖喱法?
有几个原因说明currying是理想的。
- 夤缘是一种检查方法,可以确保你在进行之前得到你需要的一切
- 它可以帮助你避免重复传递同一个变量
- 它将你的函数分为多个小函数,这些小函数可以处理一个责任。这使你的函数变得纯粹,不容易出错和产生副作用。
- 在函数式编程中,它被用来创建一个高阶函数
- 这可能是个人偏好,但我喜欢它使我的代码可读。
咖喱的工作原理是什么?
Currying是一个接受多个参数的函数。它将把这个函数转化为一系列的函数,其中每个小函数都接受一个参数。
Noncurried version//
const add = (a, b, c)=>{
return a+ b + c
}
console.log(add(2, 3, 5)) // 10
Curried version//
const addCurry =(a) => {
return (b)=>{
return (c)=>{
return a+b+c
}
}
}
console.log(addCurry(2)(3)(5)) // 10
Javascript中的Currying在定义上可能有点难以理解,但随着我们的实现,它将变得清晰。
所以,让我们深入了解更多的代码例子。
例一。一个简单的、三参数的函数
首先,我将创建一个接受三个参数的简单函数。
const add =(a, b, c)=>{
return a+b+c
}
console.log(add(2, 3, 5)) // 10
输出这个函数后,结果是10 。
这里发生的事情是,这个函数是将我们所传递的所有数字参数相加。
现在,这第一个例子只是一个接受多个参数的简单函数。
我如何将一个现有的函数转换为诅咒版本?
例二。将一个现有的函数转换为一个诅咒函数
让我们试试这个第二个例子,看看如何实现咖喱函数。
在这个例子中,这个函数要接受一个参数并返回一系列的函数。
const addCurry =(a) => {
return (b)=>{
return (c)=>{
return a+b+c
}
}
}
这就是该函数的咖喱实现。如果我们输出这个,结果将是10 。
console.log(addCurry(2)(3)(5)) // 10
在第一个例子中,我们创建了一个函数addCurry ,它接受三个参数a,b, 和c, 将它们的总和a+b+c, (2)+(3)+(5),并将输出结果作为10 。
第二个例子显示了我们是如何实现同一个函数的,但是有一个咖喱版本,它接受一个参数a ,并返回一个接受另一个参数的函数b ,该函数返回一个接受另一个参数的函数c ,该函数返回它们的总和,这给我们带来了与例子一相同的输出:10 。
我们在这里所做的是一个嵌套的函数,所以这些函数中的每一个都需要一个参数,而这个参数又会返回另一个参数,并且这个函数在收到所有的参数之前不会完成。
例三。创建一个请求朋友的咖喱函数
在这个例子中,我们将创建一个简单的咖喱函数,一个用户向他的朋友John发送一个朋友请求。
const sendRequest(greet){
return function(name){
return function(message){
return `${greet} ${name}, ${message}`
}
}
}
sendRequest('Hello')('John')('Please can you add me to your Linkedin network?')
输出。
"Hello John, Please can you add me to your Linkedin network?"
我们创建了一个函数sendRequest ,它只需要一个参数,greet ,它返回人的名字和我们要发送给用户的信息。然后,当我们调用这个函数时,它就输出了信息。
基本咖喱技术与高级咖喱技术
基本的策反
const getPanCakeIngredients = (ingredient1) =>{
return (ingredient2) => {
return (ingredient3) => {
return ${ingredient1}, ${ingredient2}, ${ingredient3}; } } } getPanCakeIngredients('Egg')('flour')('milk');
这个代码例子是实现currying的基本方法。
在上面的例子中,我们创建了一个函数getPanCakeIngredients ,该函数将ingredient 1 作为一个参数,并返回一系列包含我们制作煎饼所需的其他成分的函数。
这个函数在收到所有参数之前并不完整,这意味着如果煎饼的成分不完整,这个函数就不会返回任何好的结果。
高级咖喱法
下面是一个高级咖喱的代码例子。
const curry =(fn) =>{
return curried = (...args) => {
if (fn.length !== args.length){
return curried.bind(null, ...args)
}
return fn(...args);
};
}
const totalNum=(x,y,z) => {
return x+y+z
}
const curriedTotal = curry(totalNum);
console.log(curriedTotal(10) (20) (30));
在上面的例子中,我们创建了一个需要固定数量参数的函数。
它接收一个函数curry ,作为外层函数。这个函数是一个封装函数。它返回另一个名为curried 的函数,该函数接收一个带有扩散运算符的参数( ...args) ,它比较了函数长度fn length 。
函数长度意味着无论我们在这里传递多少参数,它都会反映在函数的长度属性中。
但是参数会每次都增加。如果我们需要的参数数量不相等,它将会返回curried 。如果我们调用bind,这将创建一个新的函数,我们将传递( ...args) 。
注意,bind会创建一个新的函数。
使用ES6的现代咖喱法
作为我的额外提示,这里有一个使用ES6箭头函数实现咖喱的现代方法。它可以帮助你写更少的代码。
const sendRequest = greet => name => message =>
`${greet} ${name}, ${message}`
sendRequest('Hello')('John')('Please can you add me to your Linkedin network?')
输出。
"Hello John, Please can you add me to your Linkedin network?"
Currying可以用来操作Javascript中的DOM
准备好将currying付诸行动了吗?这里有一个简单的CodePen例子,说明如何使用curry来操作DOM。
诅咒DOM的例子
添加外部样式表/笔 任何在这里添加的URL都会按顺序添加,并在编辑器中的CSS之前。如果你链接到另一个笔,它将包括该笔的CSS。如果预处理器匹配,它将尝试在处理之前将它们结合起来。JavaScript预处理器Babel包括JJSX处理。
咖喱与部分应用
现在你知道Currying是如何工作的,那么Currying和部分应用之间有什么区别?这是程序员一直在问的一个问题。
我终于有了这个问题的答案。但在我用一些代码例子深入解释之前,我们最好先熟悉一下它们的定义。
- Currying:一个接受多个参数的函数。它将把这个函数转化为一系列的函数,每一个小函数都接受一个参数,直到所有参数都完成为止
- 部分应用:当一个函数被赋予的参数少于它所期望的参数时,它被部分应用,并返回一个期望剩余参数的新函数
知道了这些定义还不足以让我们理解它们的区别。你已经看到了咖喱的作用,但这是一个部分应用的例子。
const addPartial=(x,y,z) => {
return x+y+z
}
var partialFunc= addPartial.bind(this,2,3);
partialFunc(5); //returns 10
我们在这里所做的并不是一个卷曲的版本,但是我们做了一个addPartial 函数的部分应用。我们创建了一个简单的函数,将一列数字相加并返回其输出。
注意,当一个函数传递的一些参数不完整时,它就被称为部分应用。
咖喱和部分应用其实没有什么不同,它们是相关的,但它们有不同的理论和应用。
部分应用将一个函数转换为另一个函数,但其算数较小。
结论
对于开发者来说,currying可能感觉很复杂。虽然它很难理解,但当你在你的JavaScript项目中实现它时,你会更好地学习它。
我已经在我的一些项目中实现了currying,并通过实践来学习。这些是我用currying做的一些事情。
- 咖喱可以用来操作Javascript中的DOM
- 它可以用来触发事件监听器
- 当你想创建一个只接收单个参数的函数时,可以使用Currying。
谢谢你阅读这篇文章,如果你有任何意见,请随时留言。我很愿意向你学习。谢谢!
The postUnderstanding JavaScript curryingappeared first onLogRocket Blog.