为什么这个curried方法需要由函数包装?

时间:2015-11-18 23:17:04

标签: javascript functional-programming lodash

在下面的示例中,我希望可以将curried函数作为谓词传递给any函数。但是,它只会在包裹curried函数时产生正确的结果。为什么会出现这种情况?

var isGreaterThanOneCurried = _.curryRight(_.gt, 2)(1);
var isGreaterThanOneNoCurry = function(value) { return value > 1; };
var listOfOnes = [1, 1];    

// CORRECT! returns false
_.any(listOfOnes, function(value) { return isGreaterThanOneCurried(value); }); 

// INCORRECT! returns true
_.any(listOfOnes, isGreaterThanOneCurried); 

// CORRECT! returns false
_.any(listOfOnes, isGreaterThanOneNoCurry); 

1 个答案:

答案 0 :(得分:2)

正如_.some的文档中所述(_.any_.some的别名):

  

谓词绑定到thisArg并使用三个参数调用:   (value,index | key,collection)。

虽然你已经从右边开始,但是函数仍然接受多个参数(即使curried函数,根据定义,不应该接受多个参数,lodash在这里与这个定义相矛盾)。那些多个参数是从左到右提供的,所以你最终得到的是一个如下所示的参数列表:

[1, 0, [1, 1], 1]

前三个是由_.any提供的,最后一个是你在右边晃动后提供的。

您可以非常轻松地验证这一点:

var _ = require('lodash')

var listOfOnes = [1, 1]

function logArgsify(fn) {
  return function() {
    console.log(JSON.stringify(Array.from(arguments)))
    return fn.apply(null, arguments)
  }
}

var gt = logArgsify(_.gt)

var isGreaterThanOneCurried = _.curryRight(gt, 2)(1)

_.any(listOfOnes, isGreaterThanOneCurried)
// Output: [1,0,[1,1],1]
  • 第一个参数是1(值)

  • 第二个参数是0(索引)

  • 第三个参数是[1,1](集合)

  • 第四个参数:1,前面提供的

  • _.gt只考虑两个参数

  • 1> 0是真的