Narzędzia wiszące na brudnej ścianie warsztatu.

Destrukturyzacja – Powtórka przed ReactJS #3

Hermetyzacja, enkapsulacja, polimorfizm czy chociażby tytułowa destrukturyzacja. Długo wymieniać pojęcia, których sama nazwa wystarcza, aby początkującemu włosy stanęły dęba. Skoro zdecydowano się na użycie tak wyszukanej formy językowej, to każdy młody programista słusznie zastanawia się, jakie szataństwo musi się za tym wszystkim kryć. Na całe szczęście, bardzo często okazuje się, że wyszukane nazewnictwo niewiele ma wspólnego z poziomem trudności samej koncepcji. Destrukturyzacja, mimo że jest czymś całkowicie nowym w JavaScript, nie jest wyjątkiem od tej reguły.

Co omówię tym razem? Zobaczmy:

  1. Czym jest destrukturyzacja?
  2. Destrukturyzacja tablic
  3. Destrukturyzacja obiektów
  4. Wartości domyślne
  5. Praktyczne zastosowanie destrukturyzacji

Aby tradycji stało się zadość, na końcu wpisu czekają odnośniki do praktycznych zadań, które pozwolą przekuć teorię na praktyczne umiejętności.

Czym jest destrukturyzacja?

Jak trafnie stwierdził Kyle Simpson w książce ECMAScript 6 i dalej, manualne przypisanie indeksowanej wartości z tablicy lub właściwości z obiektu można nazwać przypisaniem strukturalnym.

Okej, ale co to ma wspólnego z tą tajemniczą destrukturyzacją. Podążając za wywodem Kyle’a, możemy spodziewać się operacji o odwrotnym działaniu do zaprezentowanej w powyższym przykładzie. Zobaczmy, jak to wygląda w praktyce.

Przy pierwszym kontakcie z taką składnią, jedyne, czego można oczekiwać, to wielkiego znaku zapytania nad głową. Skąd te nawiasy otaczające nazwy naszych zmiennych? Jakim cudem wartości zostają przypisane do poszczególnych pojemników? Gdzie podziała się zwrócona tablica?

Przypisanie destrukturyzujące to wyrażenie, które pozwala odpakować wartości z tabeli lub obiektu do osobnych zmiennych. Jest to możliwe poprzez symetryczne odwrócenie wzorca przypisania. Część lewostronna jest traktowana jako wzorzec dla dekompozycji wartości z tablicy/obiektu.

Jeżeli wzorzec nie zostanie sparowany z wartością, to zmienna otrzyma wartość undefined. Obiekt zwracany przez funkcję bar nie posiada właściwości a, stąd nie została do niej przypisana wartość liczbowa. Jeżeli masz problem z zrozumieniem działania funkcji bar, zapraszam do przeczytania mojego wpisu nt. funkcji strzałkowych.

Okej, jesteśmy w stanie odpakować wartości z obiektu i tablicy, używając przy tym nowej, wypasionej składni. Czy to wszystko, co destrukturyzacja ma do zaoferowania?

Destrukturyzacja tablic

Skoro znamy już podstawy składni, możemy przejść do ciekawszych sztuczek.

Jeżeli chcemy pominąć wybrany element, wstawiamy w jego miejsce przecinek. Pozwala to na selektywne odpakowanie zawartość zwracanej tablicy.

Jeżeli zależy nam na przypisaniu kilku elementów i przydzieleniu pozostałej części tablicy do osobnych zmiennych, wystarczy użyć rest operatora.

Jeżeli operator nie będzie w stanie odnaleźć żadnej wartości do przypisania, zmienna zostanie pustą tablicą.

Tak się składa, że destrukturyzacja tablic wykorzystuje iterator, aby dostać się do wartości źródłowej. Dzięki temu, możemy użyć tej składni dla każdej iterowalnej wartości. Poza tablicami, zaliczamy do nich: łańcuchy, mapy, zbiory oraz struktury zwracane przez operacje nad DOM.

Nieudana destrukturyzacja tablicy

Jeżeli wykorzystujemy składnię tablicową const [a, b], to przy próbie przypisania z źródła, które nie jest iterowalne, silnik wyrzuca TypeError.

Jeżeli nie mamy stuprocentowej pewności co do przetwarzanych przez destrukturyzację wartości (np. funkcje asynchroniczne), należy zachować szczególną ostrożność.

Destrukturyzacja obiektów

Nic nie stoi na przeszkodzie, aby nazwa zadeklarowanych zmiennych różniła się od nazw właściwości obiektu, który poddajemy destrukturyzacji. Jednak, wiąże się to z zastosowaniem składni, która początkowo może wydawać się pokrętna.

Świat staje na głowie, wszystko na odwrót. Jak widać, po lewej stronie mamy do czynienia z wzorcem źródło -> cel. Tradycyjne przypisanie korzysta z wzorca cel <- źródło. Bez paniki, jak to w programowaniu bywa, po przerobieniu kilku przykładów, wszystko zaskoczy na swoje miejsce.

Destrukturyzacja pozwala na wykorzystanie obliczanych kluczy własciwości. Chodzi tutaj o nazwy właściwości obliczane z wartości zmiennej, co umożliwia notacja nawiasowa [].

Nieudana destrukturyzacja obiektu

Podobnie jak w przypadku tablic, musimy uważać na konwersję wartości prymitywnych. Większość z nas jest przyzwyczajona do mechaniki metody Object(). Opakowuje ona wartość prymitywną w odpowiedni obiekt.

Polityka wobec null i undefined jest bardzo liberalna. Sytuacja wygląda inaczej w przypadku metody ToObject(), która jest wykorzystywana za kulisami podczas destrukturyzacji.

Dodatkowo, jeżeli rozpoczniemy naszą instrukcję od klamer, silnik zinterpretuje je jako wyznaczenie granic bloku. Chcąc wykorzystać destrukturyzację, warto trzymać się inicjalizacji zmiennych. Jeżeli zależy nam na przypisaniu, możemy wykorzystać obejście z nawiasami.

Wartości domyślne

Na wypadek niedopasowania wartości z źródła, destrukturyzacja pozwala na wykorzystanie opcjonalnej funkcjonalności. Możemy zabezpieczyć się przed przypisaniem undefined do zmiennej, definiując wartość domyślną.

Co ciekawe, wartość domyślna może odwoływać się do zmiennej z tego samego wzorca.

Oczywiście, należy pamiętać, że wartość domyślna zostanie obliczona tylko, jeżeli jest to potrzebne. Wartość dopasowana z źródła ma pierwszeństwo.

Praktyczne zastosowanie destrukturyzacji

Udało nam się zgromadzić całkiem pokaźny zasób nowej składni. Zobaczmy, jak to się przekłada na nasze zdolności rozwiązywania problemów.

Destrukturyzacja tablic zwracanych przez metody

W JavaScript jest kilkanaście metod wbudowanych, które zwracają tablice. Często zależy nam na konkretnych elementach, a nie samej tablicy. Dobrym przykładem, który wręcz prosi się o zastosowanie destrukturyzacji, jest String.prototype.split().

Importowanie w CommonJS

Jako że nie zdążyliśmy jeszcze zrobić powtórki z modułów w ES6, to na pewno część z Was wykorzystuje format CommonJS. Destrukturyzacja pozwala na import tylko tych funkcji, które będą dla nas użyteczne.

Zamiana wartości

Konieczność używania zmiennej pomocniczej, przy tak prostej operacji jak zamiana wartości, zawsze była dla mnie deprymująca.

Destrukturyzacja parametrów

Najlepsze zostawiłem na koniec. Wiele z pisanych przez nas funkcji przyjmuje obiekt jako parametr. Programując w oparciu o standard ES5, musimy jawnie zabezpieczyć się przed wartością undefined, po czym ustawić wartość domyślną dla każdej z właściwości. Dopiero wtedy możemy przejść do pisania części właściwej (tudzież przykładowego console.log'a). Powoduje to powstanie dużej ilości linijek kodu, z których niewiele wynika. Na szczęście, destrukturyzacja znacznie poprawia naszą sytuację.

Biorąc pod uwagę ilość okazji do powstania błędów i czytelność obydwóch przykładów, destrukturyzacja z nawiązką wynagradza swoją osobliwą składnię.

Podsumowanie

Destrukturyzacja jest niewątpliwie najtrudniejszą funkcjonalnością, jaką dotychczas omówiłem. Mimo to, naprawdę warto poświęcić czas na jej zrozumienie. Ze względu na wartości domyślne i możliwość zastosowania tego mechanizmu wobec parametrów, otrzymujemy niesamowite narzędzie pracujące na rzecz utrzymywalności i czytelności naszego kodu. Jeżeli ktoś po przeczytaniu wpisu nadal ma problem ze zrozumieniem mechaniki tego wyrażenia, polecam przeczytać dogłębny opis autorstwa Axela Rauschmayera.

Zachęcam do śledzenia bloga na facebooku. Ponadto jestem dumnym posiadaczem lekko zakurzonego Twittera (powoli wraca do życia) i raczkującego profilu na LinkedIn.

Ależ ten czas szybko leci, jesteśmy na półmetku powtórki z ES6. W kolejny poniedziałek przybliżę Wam operator spread oraz parametry rest i default.

Zadania praktyczne

Każdy z odnośników prowadzi do edytora online z treścią zadania i przygotowanym środowiskiem. Na pewno nie chcesz, aby czas poświęcony na przeczytanie tego wpisu poszedł na marne. Najlepszym sposobem na utrwalanie wiedzy jest praktyka.

Źródła

Zdjęcie tytułowe autorstwa:

Arthur Lambillotte

Marcin Czarkowski

Cześć! Ja nazywam się Marcin Czarkowski, a to jest AlgoSmart - blog, na którym dzielę się wiedzą o ReactJS, JavaScript oraz CSS. Od niedawna tworzę materiały na YouTube, warto rzucić okiem :).