我看到了一个奇怪的函数,看起来像:
const x = (a) => (b) => a + b;
console.log(x(1)(2))
输出为3,我知道这是一个返回函数的函数,a和b都在同一范围内,但是我的问题是:
答案 0 :(得分:9)
通过这种关闭,您可以获得具有恒定值的函数以供以后添加。
- 如何在现实生活中使用它?
您可以将返回的函数用于数组的映射。
- 不使用带有2个参数的函数而是使用它(对于单行函数)有什么好处?
这是一种更干净实用的方法。
const
x = a => b => a + b,
add5 = x(5);
console.log([1, 2, 3].map(add5));
答案 1 :(得分:3)
让我们给该函数起一个更好的名字:
const add = (a) => (b) => a + b
然后您可以写
[1, 2, 3, 4] .map (add (5)) //=> [6, 7, 8, 9]
比它好读
[1, 2, 3, 4] .map ((n) => 5 + n) //=> [6, 7, 8, 9]
在承诺.then()
链中,这很方便:
return fetchList (param)
.then (map (add (5)))
.then (filter (lessThan (8)))
.then (average)
(这当然需要咖喱函数add
,lessThan
,map
和filter
,以及一些简单的average
函数。)
将此与
进行比较 return fetchList (param)
.then (xs => xs.map (x => add (5, x)))
.then (xs => xs.filter (x => lessThan (8, x)))
.then (average)
请注意,average
在这两个版本中均起作用的原因是
接受一个参数。 curry的主要要点是将一个函数转换为一个带有单个参数的函数。它使某种编码风格更易于执行。
答案 2 :(得分:2)
尼娜给出了一个很好的答案。我将提供另一个更高级的示例,其中这种闭包对代码的清晰性有很大帮助。让我们将函数组合成一个前缀检查器,如下所示,然后根据需要重复使用它多次:
//given a word, check if a string s starts with this word
const literal = word => s => s && s.startsWith(word);
//allow to combine 2 literals with OR
const either = (p1, p2) => s => p1(s) || p2(s);
//allow to combine N literals
const any = (...parsers) => parsers.reduce(either);
//create a parser
const check = any(literal('cat'),literal('dog'),literal('cow'));
console.log('cat: ' + check('cat'));
console.log('dog: ' + check('dog is smart'));
console.log('cow: ' + check('cow 123'));
console.log('banana: ' + check('banana'));
实际上,它是简化的解析器组合器(不是,还不是单子)。扩展这种方法,您可以为自己的编程语言创建解析器,并且该解析器将可维护且快速。