2015-09-12 18 views
5

Próbowałem dowiedzieć się więcej o programowaniu funkcjonalnym, patrząc na dokumentację podkreślenia i próbując napisać własne wersje najczęściej używanych funkcji.Wdrażanie i zrozumienie funkcji "pamiętaj" w podkreśleniu & lodash

Przechodząc przez "memoize" - miałem kłopot z owinięciem głowy i znalazłem informację w "Dobrej części" Crockforda.

_.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; 
    }; 

mógłbyś mi pomóc zrozumieć, jeśli mój wykorzystanie .apply było nawet konieczne, a jeśli istnieje jakakolwiek poprawa rdzeń mogę zrobić z tym kodem? Naprawdę doceniam pomoc!

+0

Tak, użycie polecenia jest konieczne, ponieważ nie jesteś świadomy, ile argumentów 'func' będzie miał –

+0

Więc to jest kod, który sam napisałeś? I nic nie rozumiesz? Albo które części podkreślenia nie rozumiesz? – Bergi

+0

@Bergi - Udało mi się dotrzeć do tego rozwiązania, ale chciałem sprawdzić, czy były jakieś błędy lub ulepszenia, które mogłem wprowadzić. Jak wspomniałem poniżej, od tego czasu zmieniłem użycie typeof i polegam na hasOwnProperty. Jednak staram się dowiedzieć, w jaki sposób mogę zapobiec uruchomieniu funkcji memoized więcej razy, niż to konieczne. – tsaiDavid

Odpowiedz

6

Istnieje kilka oczywistych problemów z poprawności:

1) buforować wynik opiera się jedynie na wartości pierwszy argumentu, więc wywołanie funkcji z różnych argumentów będzie produkować zły wynik!

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

2) użyć undefined reprezentować funkcję, która nie została jeszcze nazwie, ale undefined jest ważna wartość zwracana. Zobacz, jak efekt uboczny dzieje dwukrotnie:

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

Można zamiast tego użyć cache.hasOwnProperty wykryć, czy coś jest w pamięci podręcznej.

Polecam, aby napisać zestaw testowy. Testy są dość cenne w znajdowaniu tych błędów. Wymyśl inne, skrajne przypadki, w których Twoja funkcja może nie działać prawidłowo. Samodzielne narzędzia, takie jak to, naprawdę nadają się do kodowania sterowanego testami.

+0

Hej, dziękuję bardzo za wyraźną odpowiedź. Jest bardzo pomocny. Poszedłem dalej i wziąłem pod uwagę, biorąc pod uwagę, że użycie "niezdefiniowanej" może nadal zwracać prawidłową wartość zwrotu. Zamiast tego zamieniłem wiersz na 'if (! Cache.hasOwnProperty (result)) {' – tsaiDavid

+1

Pomyśl o 'var log = memoize (console.log.bind (console)); log ("hasOwnProperty"); log ("hasOwnProperty"); ' – Bergi