奇怪的函数语法

时间:2019-07-02 18:07:07

标签: javascript

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

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

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

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

  1. 如何在现实生活中使用它?
  2. 不使用带有2个参数的函数而是使用它(对于单行函数)有什么好处?

3 个答案:

答案 0 :(得分:9)

通过这种关闭,您可以获得具有恒定值的函数以供以后添加。

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

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

  
      
  1. 不使用带有2个参数的函数而是使用它(对于单行函数)有什么好处?
  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)

(这当然需要咖喱函数addlessThanmapfilter,以及一些简单的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'));

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