2017-02-17 61 views
1

我有代码使用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));)不起作用?

+0

只用'return fn(n.concat(m));' – madox2

回答

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) 
+0

'apply'如何将n.concat(m)转换为数组而不是数组? –

+1

@YoussefMohamed它只是做。 'apply'是一个内置函数,它可以执行平台所能做的任何事情。我不知道有一种方法可以在不依赖底层运行时的情况下实现这种行为。你可能会问,为什么'var foo = 3'将值3绑定到'foo'这个名字,所以你可以重新使用它。就JavaScript而言,它的魔力。 –

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