Sto lavorando per riscrivere il codice sottostante per molte delle funzioni standard di Underscore.js lavoro sulle mie competenze JavaScript e sono un po 'bloccato con lo _.every
/_.all
. Sembra che nella libreria stessa, la funzione _.every
/ venga scritta solo utilizzando la funzione esistente _.each
, ma sono incoraggiato a scrivere una versione utilizzando la mia versione di _.reduce
(che incorpora già la mia versione di _.each
). Ho fornito il codice per entrambe le funzioni di seguito.Come riscrivere _.every/_. Tutto da Underscore.js utilizzando _.reduce (e _.each)
Il primo test mia _.every
funzione (vedi sotto pure) non è quella in cui sono passati tutti i falsi valori utilizzando la funzione _.identity
(semplicemente valore inserito come argomento di ritorno) come iteratore:
Test:
it('fails for a collection of all-falsy results', function() {
expect(_.every([null, 0, undefined], _.identity)).to.equal(false);
});
ho alcune domande sul perché la mia funzione _.every
sta fallendo la prova mostrato sopra, insieme a più di altri test (ad esempio, misti vero/falso valori, valori non definiti, etc.):
-Quando si chiama la funzione iteratore, devo usare iterator.call
o iterator.apply
? Se sì, quale uso e come posso specificare gli argomenti?
-Quale vantaggio è quello di utilizzare _.reduce
qui anziché solo _.each
, in particolare quando la libreria Underscore.js non utilizza _.reduce
?
-Perché fa restituire la necessità di essere chiamato due volte, una volta che quando si chiama la funzione _.reduce
, e una volta all'interno della funzione anonima definita all'interno _.reduce
(ho anche chiesto questo quando si costruisce le funzioni che utilizzano la funzione _.map
)? A me sembra che sto restituendo il risultato della funzione _.reduce
, che sta già restituendo qualcosa.
_.every:
_.every = function(collection, iterator) {
// TIP: Try re-using reduce() here.
return _.reduce(collection, function(allFound, item) {
return iterator(item) && allFound;
}, true);
};
_.each:
_.each = function(collection, iterator) {
// define spec for arrays
if (Array.isArray(collection)) {
for(var i = 0; i < collection.length; i++) {
iterator(collection[i], i, collection);
}
}
// define spec for objects
else {
for(var key in collection) {
iterator(collection[key], key, collection);
}
}
};
_.reduce:
_.reduce = function(collection, iterator, accumulator) {
// add condition to set accumulator if no explicit starting value is given.
if (arguments.length < 3) {
accumulator = collection[0];
}
_.each(collection, function(value) {
accumulator = iterator(accumulator, value);
});
return accumulator;
};