我在一些文章和博客中看到了curry函数的引用,但我找不到一个好的解释(或者至少一个有意义的解释!)
当前回答
它可以是一种用函数生成其他函数的方法。
在javascript中:
let add = function(x){
return function(y){
return x + y
};
};
我们可以这样称呼它:
let addTen = add(10);
运行时,将10作为x传入;
let add = function(10){
return function(y){
return 10 + y
};
};
这意味着我们返回这个函数:
function(y) { return 10 + y };
所以当你打电话的时候
addTen();
你真的在呼唤:
function(y) { return 10 + y };
如果你这样做:
addTen(4)
这就相当于:
function(4) { return 10 + 4} // 14
所以我们的addTen()总是给我们传入的任何东西加10。我们可以用同样的方法来构造类似的函数:
let addTwo = add(2) // addTwo(); will add two to whatever you pass in
let addSeventy = add(70) // ... and so on...
接下来的问题是,你到底为什么要这么做?它将一个急迫的操作x + y变成了一个可以轻松完成的操作,这意味着我们至少可以做两件事 1. 缓存昂贵的操作 2. 在功能范式中实现抽象。
想象我们的咖喱函数是这样的:
let doTheHardStuff = function(x) {
let z = doSomethingComputationallyExpensive(x)
return function (y){
z + y
}
}
我们可以调用这个函数一次,然后将结果传递给很多地方,这意味着我们只做一次计算上昂贵的事情:
let finishTheJob = doTheHardStuff(10)
finishTheJob(20)
finishTheJob(30)
我们可以用类似的方式得到抽象。
其他回答
curry是将函数从可调用的f(a, b, c)转换为可调用的f(a)(b)(c)。
另外,curry是指将一个接受多个参数的函数分解为一系列接受部分参数的函数。
从字面上看,curry是函数的转换:从一种调用方式到另一种调用方式。在JavaScript中,我们通常创建一个包装器来保留原始函数。
curry不调用函数。它只是变换了它。
让我们创建一个curry函数,它对双实参函数执行curry。换句话说,对于双参数f(a, b)的curry(f)将其转换为f(a)(b)
function curry(f) { // curry(f) does the currying transform
return function(a) {
return function(b) {
return f(a, b);
};
};
}
// usage
function sum(a, b) {
return a + b;
}
let carriedSum = curry(sum);
alert( carriedSum(1)(2) ); // 3
如您所见,实现是一系列的包装器。
curry(func)的结果是一个包装器函数(a)。 当它像sum(1)一样被调用时,参数被保存在词法环境中,并返回一个新的包装器函数(b)。 然后sum(1)(2)最后调用函数(b)提供2,它将调用传递给原始的多参数sum。
这里有一个具体的例子:
假设你有一个计算作用在物体上的引力的函数。如果你不知道公式,你可以在这里找到。这个函数接受三个必要的形参作为参数。
现在,在地球上,你只想计算这个星球上物体的力。在函数式语言中,你可以把地球的质量传递给函数,然后对它进行部分计算。你会得到另一个函数,它只接受两个参数,并计算地球上物体的引力。这叫做咖喱。
下面是JavaScript中的一个curry示例,这里的multiply返回用于将x乘以2的函数。
const multiply = (presetConstant) => {
return (x) => {
return presetConstant * x;
};
};
const multiplyByTwo = multiply(2);
// now multiplyByTwo is like below function & due to closure property in JavaScript it will always be able to access 'presetConstant' value
// const multiplyByTwo = (x) => {
// return presetConstant * x;
// };
console.log(`multiplyByTwo(8) : ${multiplyByTwo(8)}`);
输出
multiplyByTwo(8): 16
正如所有其他答案一样,咖喱有助于创建部分应用函数。Javascript不提供自动咖喱的原生支持。因此,上面提供的示例可能对实际编码没有帮助。在livescript中有一些很好的例子(基本上编译成js) http://livescript.net/
times = (x, y) --> x * y
times 2, 3 #=> 6 (normal use works as expected)
double = times 2
double 5 #=> 10
在上面的例子中,当你给出较少的no of参数时,livescript会为你生成新的curried函数(double)
curry是指将一个接受多个参数的函数分解为一系列函数,每个函数只接受一个参数。下面是JavaScript的一个例子:
function add (a, b) {
return a + b;
}
add(3, 4); // returns 7
这是一个接受两个参数a和b的函数,并返回它们的和。现在我们将咖喱这个函数:
function add (a) {
return function (b) {
return a + b;
}
}
这是一个接受一个参数a的函数,并返回一个接受另一个参数b的函数,该函数返回它们的和。
add(3)(4); // returns 7
var add3 = add(3); // returns a function
add3(4); // returns 7
第一个语句返回7,就像add(3,4)语句一样。 第二条语句定义了一个名为add3的新函数 给它的参数加上3。(这就是有些人所说的终结。) 第三条语句再次使用add3操作将3添加到4 结果是7。
推荐文章
- 如何为Firebase构建云函数,以便从多个文件部署多个函数?
- 如何发送推送通知到web浏览器?
- AngularJS:工厂和服务?
- js:将一个组件包装成另一个组件
- 父ng-repeat从子ng-repeat的访问索引
- JSHint和jQuery: '$'没有定义
- 模仿JavaScript中的集合?
- 用JavaScript验证电话号码
- 如何在HTML5中改变视频的播放速度?
- 谷歌地图API v3:我可以setZoom后fitBounds?
- ES6/2015中的null安全属性访问(和条件赋值)
- 与push()相反;
- JS字符串“+”vs concat方法
- AngularJS使用ng-class切换类
- 访问Handlebars.js每次循环范围之外的变量