Programowanie funkcyjne w JavaScript – poznajemy funkcje wyższego rzędu. Do dzieła.

Przypomnijmy sobie, jak działał pipe:

const pipe = (...fns) => (data) => fns.reduce((acc, fun) => fun(acc), data);

Czyli możemy wziąć wartość, np. „16px”. Możemy ją wpuścić w funkcję zwróconą przez pipe, która przyjmie funkcje:

  • parseInt zamieniający „16px” na liczbę 16 i zwracający ją
  • convertToRem konwertujący 16 (w pikselach) na jego odpowiednik w Rem
  • addOneRem przyjmujący wartość i dodający i Rem
  • I tak dalej i tym podobne

Krótko mówiąc, funkcja następna wywołuje się na wartości zwróconej przez wartość poprzednią.

A co jeśli chcemy pipować po prostu niezależne od siebie manipulacje na tym samym elemencie? Chcemy wykonać je sekwencyjnie, na tym samym elemencie?

Przy takiej konstrukcji pipe wyglądałoby to mniej więcej tak:

let para = new PipedElement("p", 
    (para) => {
        para.textContent = "New Para";
        return para;},
    (para) => {
        para.classList.add("text-primary");
        return para;
    }
);

Oczywiście funkcję-konstruktor musielibyśmy napisać. Dużo pisania, mało czytelności i ułatwienia.

Napiszmy sobie funkcję pipedManipulation, która przyjmuje funkcje do wywołania na tym samym elemencie:

function pipedManipulation(...fns){
    return function(subject){
         fns.forEach((func) => {
            func(subject);
        });
    }
}

Teraz przykład użycia:

let btn = document.querySelector("#btn");

const manipulate = pipedManipulation(
    (el) => el.textContent = 'pipedTransform',
    (el) => el.classList.add("btn-secondary"),
);

manipulate(btn);

Nie mamy tutaj zwracania textcontent do następnej funkcji – każda z nich jest wykonywana niezależnie, ale sekwencyjnie i na tym samym elemencie.

Funkcje mogą być bardziej skomplikowane, np. ustawiać jakiś textContent tylko wtedy, gdy nie jest ustawiony, przypisywać event listener tylko wtedy, gdy atrybut href zaczyna się od „#” i tak dalej.

Natomiast mamy tu do czynienia z funkcją wyższego rzędu. W pipe też mieliśmy, ale składnia strzałkowa pozwoliła mi to wtedy przemilczeć, żeby jeszcze bardziej w głowie nie mieszać.

Cóż, funkcje wyższego rzędu. W nowoczesnym programowaniu nie na się bez nich żyć.