2015-09-12 14 views
5

Si è cercato di imparare di più sulla programmazione funzionale osservando la documentazione di sottolineatura e tentando di scrivere le mie versioni delle funzioni più utilizzate.Implementazione e comprensione della funzione "memoize" in underscore & lodash

Trovarsi in "memoize" - Avevo difficoltà a sistemare la mia mente intorno a esso, e ho trovato alcune informazioni in "The Good Parts" di Crockford.

_.memoize = function(func) { 
    // 'cache' object is used to hold the result of the memoized fn's call 
    var cache = {}; 
    var recur = function(n) { 
     var result = cache[n]; 
     if (typeof result === 'undefined') { 
     result = func.apply(this, arguments); 
     cache[n] = result; 
     } 
     return result; 
    } 
    return recur; 
    }; 

La prego di aiutarmi a capire se il mio uso di .Applicare era ancora necessario e se non v'è alcun miglioramento nucleo posso fare a questo codice? Apprezzo davvero l'aiuto!

+0

Sì, l'uso di apply è necessario perché non si è a conoscenza di quanti argomenti 'func' avrà –

+0

Quindi questo è il codice che hai scritto tu stesso? E non c'è niente che non capisci a riguardo? O quali parti del trattino basso non capisci? – Bergi

+0

@Bergi - Sono riuscito ad arrivare a questa soluzione, ma volevo vedere se c'erano errori o miglioramenti che potevo fare. Come ho detto di seguito, ho cambiato l'uso di typeof e ho fatto affidamento su hasOwnProperty. Tuttavia, sto cercando di capire come evitare che la funzione memorizzata funzioni più volte del necessario. – tsaiDavid

risposta

6

ci sono alcuni problemi evidenti con correttezza:

1) di mettere in cache il risultato basato solo sul valore dell'argomento prima, quindi chiamare una funzione con argomenti diversi produrrà un risultato sbagliato!

let add = memoize((a, b) => a + b) 
add(1, 2) 
> 3 
add(1, 3) 
> 3 

2) Si utilizza undefined di rappresentare una funzione che non è stato ancora definito, ma undefined è un valore di ritorno valido. Vedere come l'effetto collaterale avviene due volte:

let log = memoize(() => console.log('hello')) 
log() 
> hello 
log() 
> hello 

È possibile invece utilizzare cache.hasOwnProperty per rilevare se qualcosa è nella cache.

Ti consiglio di scrivere una suite di test. I test sono abbastanza preziosi nel trovare questi bug. Pensa ad altri casi limite in cui la tua funzione potrebbe non funzionare correttamente. Utilità standalone come questa si prestano davvero alla codifica basata su test.

+0

Ehi, grazie mille per la risposta chiara. È molto utile Sono andato avanti e refactored tenendo conto che l'utilizzo di 'undefined' potrebbe ancora restituire un valore di ritorno valido. Ho sostituito la riga con 'if (! Cache.hasOwnProperty (result)) {' – tsaiDavid

+1

Pensa a 'var log = memoize (console.log.bind (console)); log ("hasOwnProperty"); log ("hasOwnProperty"); ' – Bergi

Problemi correlati