如何使用适用于currying?

时间:2017-02-17 17:19:54

标签: javascript currying

我的代码使用currying来获取连接两个数组的数组的平均值:n个数组和m个数组。

var avg = function(...n){ 
  let tot=0;
  for(let i=0; i<n.length; i++){
    tot += n[i];
  }
  return tot/n.length;
};

var spiceUp = function(fn, ...n){
  return function(...m){
    return fn.apply(this, n.concat(m));
  }
};

var doAvg = spiceUp(avg, 1,2,3);
console.log(doAvg(4,5,6));

在这一行return fn.apply(this, n.concat(m));中,我不明白为什么我们需要使用apply。我们与普通函数绑定的对象是什么?为什么普通调用(return fn(n.concat(m));)不起作用?

2 个答案:

答案 0 :(得分:1)

在该示例中,this并不重要。如果不是这样,你也会传递一个空对象。它只是一个如何使用apply的例子。

您需要关注的是第二个参数n.concat(m)。这里的关键概念是将数组作为第二个参数传递,您调用该函数(fn)将数组中的每个值作为参数传递。

关于你的第二个问题:不,它不会起作用,因为fn需要几个参数(每个值计算一个平均值),而return fn(n.concat(m));你只是传递一个参数,包含所有值的数组

也许你会通过一个更简单的例子更好地理解它:

function sum3params(a,b,c){
    return a+b+c;
}

console.log(sum3params([3,4,2])) // won't work
console.log(sum3params.apply(this, [3,4,2])) // will work ('this' is not important here)

答案 1 :(得分:1)

对于这个用例,它没有。但请考虑以下因素:

var foo = {
  bar: 3
};

var addBar = function(a, b) { return a + b + this.bar };
foo.add3AndBar = spiceUp(addBar, 3);
foo.add3AndBar(1); // 7

使用apply表示您的spiceUp函数可以应用于方法和普通函数。更可能的例子是,在原型上定义方法时考虑部分应用:

const ENV = "linux";
DoesSomePlatformSpecificStuff.prototype.getPath = spiceUp(ENV);

apply也会将收集的参数数组传播回位置参数,这也可以这样做:

return fn(...n.concat(m));

可以简化为

return fn(...n, ...m);

相当于

return fn.apply(undefined, n.concat(m));