如何使用柯里化应用?

How to use apply with 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));) 不起作用?

在那个例子中,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)

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

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