js函数柯理化,javascript柯里化
本文带你快速了解Javascript中的Currying,有一定的参考价值。有需要的朋友可以参考一下,希望能帮到你。
内核函数一次接受多个参数。所以如果你有
greet=(greeting,first,last)=`${greeting},$ { first } $ { last } `;
打招呼(你好,布鲁斯,韦恩);//你好,布鲁斯韦恩可以写成这种形式
curriedGreet=curry(打招呼);
curried greet( Hello )( Bruce )( Wayne );//你好,布鲁斯韦恩
如何正确的使用?
“库里”的正确用法是因为有些库里功能使用起来更灵活。Currying理论上很棒,但是在JavaScript中为每个参数调用一个函数会很累。
Ramda的curry函数可以让你这样调用curriedGreet:
//greet需要3个参数:(greeting,first,last)
//这些都返回一个函数寻找(first,last)
currid greet( Hello );
curried greet( Hello )();
currid greet()( Hello )()());
//这些都返回一个函数寻找(last)
curried greet( Hello )( Bruce );
curriedGreet(Hello , Bruce );
currid greet( Hello )( Bruce )();
//这些函数返回一个问候,因为所有3个参数都被接受
curried greet( Hello )( Bruce )( Wayne );
curriedGreet(你好,布鲁斯,韦恩);
curriedGreet(你好,布鲁斯)()(韦恩);请注意,您可以选择一次给出多个参数。这种实现在编写代码时更有用。
如上所示,您总是可以不带参数调用这个函数,它总是会返回一个需要其余参数的函数。
工作原理相同
const curry=(f,arr=[])=(.args)=
((a)=(a.length===f.length?f(.a):库里(f,a)))([.啊,args]);让我们一起来重构和欣赏吧。
我还在debuggerChrome开发工具中添加了一些语句来检查它。
curry=(originalFunction,initialParams=[])={
调试器;
返回(.nextParams)={
调试器;
const curied function=(params)={
调试器;
if(params . length===original function . length){
返回原始函数(.params);
}
返回库里(originalFunction,params);
};
返回curied function([.初始参数,next params]);
};
};
开始
将问候和问候粘贴到您的控制台中。然后输入curriedGreet=curry(greet)开始疯狂。
在第 2 行暂停
检查我们看到的两个参数,greet的originalFunction和default initialParams是一个空数组,因为我们没有提供。移到下一个断点,哦等等…就这样。
是啊!Curry(greet)只返回一个需要3个以上参数的新函数。在控制台中键入curriedGreet,看看我在说什么。
当你做完这些,让我们变得更疯狂一点,然后做sayHello=curriedGreet(Hello )。
在第 4 行暂停
继续之前,请在控制台中输入原始功能和。InitialParams请注意,即使我们在一个全新的函数中,我们仍然可以访问这两个参数?这是因为从父函数返回的函数享有其父函数的作用域。
继承
传递完父函数后,他们把参数留给子函数使用。有点像现实生活中的继承。
Curry最初给出originalFunction,initialParams,然后返回一个“子”函数。这两个变量没有被处理掉,因为也许那个孩子需要它们。如果他没有,那么这个范围就被清空了,因为当没有人提到你的时候,就是你真正死亡的时候。
好的,回到第 4 行……
检查nextParams,并查看它是否为[hello].一个数组?但我以为我们说的是curied greet( Hello Hello ),不是curied greet([ Hello ])!
正确:我们用 Hello 调用curriedGreet,但是由于rest语法,我们变成了 Hello [Hello]。
是吗?!
curry是一个通用函数,可以提供1个、10个或10,000,000个参数,所以需要一个引用所有参数的方法。使用类似的rest语法来捕获数组中的每个参数使得curry的工作更加容易。
让我们从调试器跳到一个语句。
现在是第 6 行,但请稍等。
您可能已经注意到,第12行实际上是在调试器的第6行语句之前运行的。如果没有,请仔细看看。我们的程序在第5行定义了一个调用函数curriedFunction,在第12行使用它,然后我们的调试器单击第6行的语句。什么是curriedFunction调用?
[.初始参数,next params];呸呸。看params的第五行,你会看到[Hello]。initialParams和都是数组,所以我们使用方便的扩展操作符nextParams将它们展平并组合成一个数组。
这是好事发生的地方。
第7行说,“如果params和originalFunction长度相同,请让greet用我们的参数调用,我们就完成了。”这让我想起了…
JavaScript 函数也有长度
这就是库里的魔术!这是它决定是否要求更多参数的方式。
在JavaScript中。函数的长度属性告诉你它需要多少个参数。
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函数。它再次收到问候,这一次,“你好”,并再次开始疯狂。
这是递归,我的朋友们。
Curry本质上是一个无限循环的自我调用、渴求参数的函数,它不会休息,直到它们的客人都满了。好客。
回到第 2 行
initial params的参数与之前相同,只是这次使用了[Hello]。再次跳过退出循环。在控制台中输入我们的新变量sayHello。这是另一个函数,仍然期待更多的参数,但我们越来越温暖。
让我们把火打开。
我们又在第4行,nextParams是[John]。跳到第6行的下一个调试器并检查params:它是[Hello , John]!
为什么?
因为请记住,第12行写的是“嘿curriedFunction,他上次给了我‘你好’,这次给了我‘约翰’。将它们都带入这个数组[.初始参数,下一个参数]。"
现在curriedFunction再次比较length params和originalFunction,因为2 ^ 3我们移到第10行,curry再次调用!当然,我们传递了两个参数,[Hello , John]
我们很接近了,让我们全部完成,得到满满的问候!
sayHelloToJohnDoe=sayHelloToJohn( Doe )
我想我们知道接下来会发生什么。
结论
greet得到他的参数,curry停止循环,我们收到我们的问候:你好,John Doe。
多发挥这个功能。尝试一下子提供多个参数或者不提供参数,随你怎么疯。Curry查看在返回预期输出之前必须进行多少次递归。
curriedGreet(Hello , John , Doe );
curriedGreet(Hello , John )( Doe );
currid greet()( Hello )( John )()()()()()(( Doe );【相关视频教程推荐:web前端】以上是快速了解JS中Currying的详细内容。更多请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。