Warunkowe właściwości obiektu

Literał obiektowy nieustannie wykorzystujemy do konfigurowania bibliotek czy pluginów – nic w tym dziwnego, jego konstrukcja jest minimalistyczna a co za tym idzie bardzo czytelna. Niestety ta czytelność spada w momencie gdy właściwości mają pojawić się po spełnieniu warunku. Zobaczmy jak zrobić to elegancko i czytelnie wykorzystując destrukturyzację.

Proces tworzenia literału z konfiguracją wygląda mniej więcej tak: utwórz literał w konstrukcji {klucz: wartość} a klucze które mają pojawić się warunkowo wstaw w konstrukcje if – pyk, działa i wygląda mniej więcej tak:

const config = { foo: 'bar', }; if (someCondition === true) { config.animationDelay = 100; } $(‘body’).plugin(config);

Przy większej IFologi można uciec z czymś takim do osobnej funkcji, ale dalej gdy tam zajrzymy będziemy widzieć jeden wielki “if-oriented-programming” – jak żyć patrząc na coś takiego?

W ES2015 dostaliśmy rewelacyjne narzędzie które nazywa się – operator rozwinięcia (“spread operator”). W połączeniu z operatorem warunkowym (“ternary operator”) możemy znacznie uprościć nasz kod:

const config = { …someCondition === true ? {animationDelay: 100} : {}, };

Jeśli someCondition jest równy true, zostaje zwrócony obiekt {animationDelay: 100} – trafia na operator rozwinięcia który łączy zwrócony obiekt z docelowym. Konstrukcja wygląda teraz tak:

const config = { …{animationDelay: 100}, };

Natomiast po wykonaniu operatora rozwinięcia nasz obiekt finalnie wyglada tak:

{animationDelay: 100}

W przypadku gdy someCondition jest równy false, zostaje zwrócony pusty obiekt, który w konfrontacji z operatorem rozwinięcia powoduje że nasz obiekt konfiguracji również jest pusty.

const config = { …{}, };

Super, ale ciągłe dodawanie pustego literału po to żeby zrobić else? Nope.

Użyjmy operatora logicznego AND:

const config = { …firstCondition === true && {animationDelay: 100}, …secondCondition === true && {timeout: 100}, };

Działają tu 3 zasady:

  • Wyrażenia logiczne przetwarzane są od lewej do prawej
  • Sprawdzana jest najkrótsza możliwa ścieżka (tzw. “short-circuit evaluation”)
  • Wyrażenie zwraca ostatnią prawdziwą wartość (“truthy value”, czyli przeciwieństwo do “falsy value”)

Sprawdźmy zatem takie wyrażenie:

true && ‘test’ -> zwróci ‘test’, bo idąc od lewej pierwszy warunek zostaje spełniony więc przechodzimy do drugiego i ostatniego zarazem więc zostaje zwrócony.

false && ‘test’ -> zwróci false, bo idąc od lewej pierwszy warunek nie zostaje spełniony, dlatego też kolejne warunki nie są sprawdzane (najkrótsza droga), zostaje zwrócona ostatnia wartość, w tym wypadku false.

Inny podobny przykład z falsy values:

1 && ‘test’ -> zwróci ‘test’, bo 1 warunek zostaje spełniony (1 to truthy value) więc przechodzimy do 2

0 && ‘test’ -> zwróci 0, bo 1 warunek nie zostaje spełniony (0 to falsy value), zostaje zwrócona ostatnia wartość, w tym wypadku 0

W przypadku ostatecznej wersji wszystko jest już chyba jasne:

const config = { …firstCondition === true && {animationDelay: 100}, };

firstCondition zostaje spełniony, zatem zwrócony zostaje literał obiektowy. Ten przekazany do operatora rozwinięcia i łączy się z obiektem config.

Jestem przekonany że warunkowe właściwości obiektu to coś z czego powinno korzystać się na codzień, kod staje się bardziej zwięzły i czytelny nawet przy dużej ilości warunków. 

Mam nadzieję że nie zanudziłem a nauczyłem.

Zdjęcie: Shahadat Rahman

Dodaj komentarz

Twój adres email nie zostanie opublikowany.