2017-02-17 50 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));