返回箭头函数的箭头函数有什么用?

问题描述 投票:0回答:3

我看到一个奇怪的函数,看起来像这样:

const x = (a) => (b) => a + b;

console.log(x(1)(2))

输出是 3,我知道这是一个返回函数的函数,并且 a 和 b 都在同一范围内,但我的问题是:

  1. 这在现实生活中如何使用?
  2. 不使用具有 2 个参数的函数并使用它(对于单行函数)有什么好处?
javascript currying
3个回答
8
投票

通过这个闭包,你可以获得一个具有常量值的函数,以便稍后添加。

  1. 这在现实生活中如何使用?

您可以将返回的函数用于数组的映射。

  1. 不使用具有 2 个参数的函数并使用它(对于单行函数)有什么好处?

这是一种更干净、更实用的方法。

const
    x = a => b => a + b,
    add5 = x(5);

console.log([1, 2, 3].map(add5));


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()
调用 Promises 中非常方便:

  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
在这两个版本中的作用相同的原因是它 采用单个参数。 柯里化的一个要点是将函数转变为采用单个参数的函数。 它使某种风格的编码更容易执行。


2
投票

Nina 给出了很好的答案。我将提供另一个更高级的示例,其中此类闭包对代码的清晰度有很大帮助。让我们将函数组合成一个前缀检查器,如下所示,然后根据需要多次重复使用它:

//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'));

实际上,它是一个简化的解析器组合器(不,还不是单子)。扩展这种方法,您可以为自己的编程语言创建解析器,并且它将是可维护且快速的。

© www.soinside.com 2019 - 2024. All rights reserved.