Czytam o obecności domknięć (closure) w JavaScript i, o ile chyba rozumiem zasadę działania to, chciałbym znaleźć praktyczne zastosowania tych (rodzajów?) funkcji.
W skrócie (tak to rozumiem) - funkcja A stworzona wewnątrz innej (zewnętrznej) funkcji B, zapamiętuje jej całe ciało; co może być później wykorzystane do dalszych obliczeń.
Czyli np.:
var outer = function(outerVar)
{
return function (innerVar)
{
console.log(outerVar + ' ' + innerVar);
}
}
var resultOfBoth = outer(2);
resultOfBoth(3); // wynik = 5;
Jeśli nic nie pomieszałem to funkcja outer, w momencie jej wywołania, przechowa parametr jej przekazany - czyli 2 - zwracając funkcję inner, która będzie już ten parametr "mieć" (JS przechowa go w pamięci, ale już nie będzie "pamiętał" skąd ten parametr się tam wziął?). W momencie wywołania zmiennej(?) resultOfBoth, która przechowuje już (zwróconą) funkcję inner z parametrem 2 - przekazuje jej parametr 3. Ostatecznie funkcja inner posiada dwa parametry (2 i 3), które wyświetli w konsoli.
Teraz moja hipoteza: W domknięciu chodzi o to, aby wewnętrzna funkcja - pomimo zakończenia działania funkcji zewnętrznej - ZAPAMIĘTAŁA sobie zawartość jej ciała (czyli wszystkich zmiennych/funkcji/obiektów/parametrów, które były tam zadeklarowane w momencie jej wywołania).
Jeśli moje przypuszczenie jest prawidłowe, to czy dobrze wnioskuję, że domknięcie jest przydatne np. jeśli chcemy uzyskać wynik działania (czy też przetwarzania danych) jakiejś funkcji później? Bo jeśli domknięcie powoduje, że funkcja zadeklarowana wewnątrz (np. inner()) zapamiętuje jej całą zawartość, to gdy zostanie ona później wywołana - odtworzy przetworzone dane (funkcji outer()) nawet w innym miejscu kodu. Bo przecież nie trzeba wywoływać funkcji od razu, ale można sobie ją wywołać gdzie indziej, jeśli scope na to pozwoli lub przekaże się funkcję jako parametr.
Nie rozumiem natomiast przytoczonego przykładu w akapicie "Practical closures" z MDN:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
Jest tam pokazana zmiana rozmiaru czcionki po kliknięciu w przycisk. Biorąc pod uwagę mój tok rozumowania i użyteczności domknięć, w jakim celu użyto closure w tym przykładzie?
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
Przecież wystarczy zwykła funkcja bez "zapamiętywania" ciała funkcji zewnętrznej. Czy w tym przykładzie chodzi o co innego?
P.S. Wiem, że w dalszej części tutoriala z MDN jest więcej przykładów dla zastosowania closures, ale są one bardziej zaawansowane i stwierdziłem, że chcę najpierw zrozumieć prostsze przykłady.