metodi JavaScript Array come forEach
hanno un parametro thisArg
, che viene utilizzato come contesto per invocare la richiamata:Perché Array.prototype.reduce non ha un parametro thisObject?
array.forEach(callback[, thisArg])
come fanno every
, some
, filter
e map
. Tuttavia, reduce
e reduceRight
non hanno questo parametro. C'è qualche ragione particolare per questo, o qualche ragione per cui non è necessario?
Ad esempio, si consideri la seguente implementazione di composizione funzionale utilizzando reduceRight
:
function compose() {
var fns = [].slice.call(arguments,0);
return function result() {
return fns.reduceRight(
function (prev,cur){
return [cur.apply(this,prev)];
},
arguments
)[0];
};
}
Vorrei rendere questo "questo-consapevole", quindi le funzioni da composti sono chiamati nel contesto in cui la funzione restituito da compose
viene invocato. Attualmente sembrano essere invocati nel contesto dell'oggetto globale. Potrei fare il vecchio var self=this;
nella parte superiore della funzione result
, e usarlo come primo argomento della chiamata , dove attualmente ho this
, ma che non sarebbe necessario se lo reduce
avesse un argomento thisArg
.
Mi manca qualcosa qui e c'è qualcosa di reduce
che rende questo non necessario o inutile?
UPDATE
@kangax Sì, che mi venne in mente. Lungi da me criticare il design dell'API, ma la firma per lo reduce
mi sembra un po 'strana. Il secondo argomento opzionale funziona in modo diverso rispetto ai normali argomenti facoltativi, che in genere hanno solo un valore predefinito; invece la sua presenza o assenza modifica il comportamento, essenzialmente sovraccarico della funzione basata sulla firma (numero di argomenti). Quando il secondo parametro è assente, il primo elemento dell'array diventa il valore iniziale e la prima chiamata al callback è contro il secondo valore. Mi sembra che questo comportamento potrebbe essere facilmente emulato semplicemente chiamando
array.slice(1).reduce(fn,array[0])
invece di costruire nelle regole speciali per il caso in cui si omette il secondo argomento, che a sua volta, se la vostra presunzione è corretto, reso anche essenzialmente impossibile capire dove specificare l'argomento thisArg
. Poi di nuovo, sono sicuro che tali questioni erano già state discusse mentre le specifiche erano state messe a tacere, e potrebbero esserci buone ragioni per un simile approccio.
Probabilmente perché il secondo argomento in 'reduce' è il valore iniziale – kangax
C'è una ragione per cui è necessario farlo con' reduceRight'? Penso che si possa fare altrettanto facilmente con 'forEach' su un array' reverse'd. Edit: Credo che il mio punto sia che non stai cercando di ridurre la gamma di funzioni, ma piuttosto di eseguire un set di input attraverso le funzioni. – tJener
@tJener Ovviamente lo si può fare con forEach (come fa undercore.js), ma ho trovato una certa eleganza nell'uso di riduci/Destra. –