我试图理解一个函数是如何工作的,它使用两个括号和两个参数运行。像这样:
__init__.py
我知道如何写一个像这样的两个参数:
add(10)(10); // returns 20
如何更改该功能,以便可以使用一组参数或两个参数运行,并产生相同的结果?
感谢任何帮助。直截了当地说道。
提前致谢!
答案 0 :(得分:18)
如何更改该功能,以便可以使用一组参数或两个参数运行,并产生相同的结果?
你可以几乎这样做,但我很难想出一个很好的理由。
以下是:你检测你的函数接收了多少个参数,如果它只收到一个,你返回一个函数而不是一个数字 - 并且那个函数添加第二个数字,如果它被叫:
function add(a,b) {
if (arguments.length === 1) {
return function(b2) { // You could call this arg `b` as well if you like,
return a + b2; // it would shadow (hide, supercede) the one above
};
}
return a + b;
}
console.log(add(10, 10)); // 20
console.log(add(10)(10)); // 20
我上面说“几乎”,因为add
函数只收到一个参数,这并不能保证调用者会调用结果。他们可以写:
var x = add(10);
...永远不要调用x
现在引用的函数。
答案 1 :(得分:9)
在JavaScript中,函数可以返回函数,因为函数只是另一个对象。一个简单的实现类似于:
function add(x){
return function addOther(y){
return x + y;
};
}
由于closures和一阶函数,这是可能的。
这也允许你进行部分应用,像Ramda这样的库在很大程度上利用了它。
var addThree = add(3)
addThree(5); // 8
答案 2 :(得分:4)
要扩展T. J. Crowder和Benjamin Gruenbaum所说的内容,像Ramda这样的库(披露:我是其中一位作者)允许您转换这样一个简单的函数:
function add(a, b) {
return a + b;
}
通过将其包装在curry
函数的调用中进入讨论的样式:
var add = R.curry(function add(a, b) {
return a + b;
});
add(3, 5); //=> 8
add(3)(5); //=> 8
var add3 = add(3);
add3(5); //=> 8
我在这个问题上所知道的最好的文章是休杰克逊的Why Curry Helps。我在Favoring Curry写了一篇更详细的文章。
这是curry
的版本比Ramda中的版本稍微简单一些。它可以完成上述操作,但不会做一些Ramda用占位符值做的事情:
// here is a function that takes a function and returns a curried version
// of it, that is, a version that performs the sort of partial application
// you describe.
var curry = function(fn) {
// first, we detect how many arguments the function has.
var fnArity = fn.length;
var partialApply = function(args) {
// now, let's create a function that's curried
return function () {
// collect the previous args as the partial, and add the new
// ones you just received
var newArgs = (args || []).concat([].slice.call(arguments, 0));
// if we have "enough" arguments, we don't need any more partial
// application and we can call the function.
if (newArgs.length >= fnArity) {
return fn.apply(this, newArgs);
} else { // else we return a partially applied version
return partialApply(newArgs);
}
};
};
return partialApply([]); // a function is itself partially applied with 0 args
};
答案 3 :(得分:0)