Programowanie i WWW

Nowości w ES2021

W tym roku w ECMAScript pojawiło się kilka zmian, które zasługują na uwagę. Z jednej strony z pewnością usprawnią pracę a z drugiej ich…

W tym roku w ECMAScript pojawiło się kilka zmian, które zasługują na uwagę. Z jednej strony z pewnością usprawnią pracę a z drugiej ich nieznajomość może mieć negatywny wpływ na komfort naszej pracy.

String.prototype.replaceAll();

Zamiana fragmentów ciągów znaków na inne to dość powszechna operacja. Wykorzystujemy ją chociażby do tego aby wyeliminować niepożądane znaki z tekstu lub podmienić jakieś frazy na inne.

Do tej pory mieliśmy do dyspozycji metodę **replace**, do której wystarczyło przekazać:

  • frazę której szukamy
  • frazę którą chcemy umieścić w miejsce tej szukanej

Problem polega na tym, że taka operacja zadziała tylko dla pierwszego znalezionego wyniku. Jeżeli chcieliśmy zamienić wszystkie wystąpienia, musieliśmy wykorzystać wyrażenie regularne z flagą **global**. Np. chcąc wyszukać frazę "eduweb" musieliśmy zapisać ją tak: **/eduweb/g** i dopiero wtedy operacja była wykonana dla wszystkich wystąpień.

Teraz wystarczy wykorzystać metodę replaceAll i przekazać do niej dokładnie takie same argumenty jak w przypadku metody replace, z tą różnicą że operacja zostanie wykonana dla wszystkich powtórzeń.

Prywatne metody i właściwości klas

Z jednej strony da się zauważyć, że klasy są coraz rzadziej wykorzystywane w JavaScripcie (np. komponenty klasowe powszechnie są już uznawane jako przestarzała składnia). I podczas gdy faktycznie na froncie coraz rzadziej spotykam się z klasami, tak w przypadku Node.js i backendu mają się bardzo dobrze (np. w Nest.js).

Jak pewnie wiesz, klasy w JavaScript to nic innego jak "syntatic sugar" pod którym kryje się dziedziczenie prototypowe (eng. Prototypal inheritance). Jednym z bardziej istotnych problemów klas w JavaScripcie był brak enkapsulacji, czyli możliwości zablokowania dostępu do metod i właściwości klas. Wyjątek stanowił tutaj TypeScript, który na etapie developmentu uniemożliwiał nam sięganie po metody czy właściwości oznaczone jako "private" lub "protected".

Od ES2021 enkapsulacja jest możliwa do osiągnięcia poprzez poprzedzenie nazwy właściwości lub metody znakiem "#". Dzięki temu wskazany element przestaje być dostępny poza klasą ale możemy robić z nim co tylko chcemy wewnątrz niej.

Powyżej mamy przykład klasy w przypadku której wykorzystujemy settery i gettery (specjalne metody służące do ustalania i pobierania wartości właściwości) w przypadku właściwości **name**. Wewnątrz klasy właściwość ta poprzedzona jest symbolem "#", co oznacza że nie możemy zmodyfikować jej wartości np. odwołując się do instancji tej klasy.

To sprawia że mamy tutaj pełną kontrolę nad właściwością name i tym jakie wartości mogą do niej trafić oraz w jakiej formie jej wartość zostanie wyświetlona.

W praktyce wykorzystanie getterów, setterów i enkapsulacji ma na celu przede wszystkim zwiększenie kontroli oraz bezpieczeństwa naszego kodu (np. dzięki temu że nie umożliwimy przypadkowej zmiany wartości właściwości obiektu).

Promise.any()

Od czasów pojawienia się async / await, praca z kodem asynchronicznym stała się zdecydowanie łatwiejsza. Problem w tym, że w niektórych sytuacjach wykorzystywana jest błędnie. Dla przykładu jeżeli mamy kilka zapytań asynchronicznych, które nie zależą od siebie, oczekiwanie na ich rozwiązanie z pomocą słowa kluczowego **await** niepotrzebnie spowalnia naszą aplikację.

Oczywiście takie oczekiwanie ma sens w przypadku gdy faktycznie pobierane wartości są ze sobą połączone i do pobrania drugiej, potrzebujemy informacji o pierwszej.

Ale jeżeli taka zależność nie występuje, znacznie lepiej jest wykorzystać metodę Promise.all() do której przekazujemy tablicę obietnic czekających na rozwiązanie.

Powyżej nie ma potrzeby aby pobierać dane o tych użytkownikach niezależnie, ponieważ nie istnieją pomiędzy nimi żadne powiązania. Zależy nam wyłącznie na tym aby do zmiennej results trafiła tablica zawierająca informacje o wskazanych użytkownikach.

No i akurat tutaj faktycznie zależy nam na tym aby wszystkie obietnice wykonały się poprawnie i tym samym informacje o użytkownikach zostały pobrane.

Istnieją jednak sytuacje w których zależy nam na tym aby rozpocząć kilka akcji asynchronicznych ale realnie zareagować wyłącznie na rozwiązanie pierwszej z nich. Przykładowo jeżeli po ten sam zestaw danych kontaktujemy się z dwoma różnymi serwisami, nie ma potrzeby aby oczekiwać na odpowiedź od każdego z nich, ponieważ wystarczą nam dane pochodzące tylko z pierwszego źródła. No i w tym momencie do gry wchodzi metoda Promise.any, której rezultatem będzie wynik zwrócony przez pierwszą rozwiązaną obietnicę spośród tych, które zostały do niej przekazane.

W tym miejscu prawdopodobnie zainteresuje Cię jeszcze różnica pomiędzy metodami all, any oraz race.

  • Metoda all zwróci tablicę zawierającą rezultaty wszystkich przekazanych obietnic o ile każda z nich zostanie rozwiązana.
  • Metoda any zwróci rezultat pierwszej rozwiązanej obietnicy nawet jeżeli pozostałe zostaną odrzucone W przypadku gdy wszystkie obietnice zostaną odrzucone i wyrzucony zostanie tzw. AggregateError zawierający właściwość .errors będącą tablicą zawierającą informację o błędach.
  • Metoda race zwróci rezultat pierwszej ustalonej obietnicy, nawet jeżeli ta zostanie odrzucona.

Logical Assignment Operators

ES2021 przedstawia również logiczne operatory przypisania, które umożliwiają przypisanie wartości w zależności od tego czy dany warunek jest spełniony.

Aby je w pełni zrozumieć, należy zwrócić uwagę na to w jaki sposób JavaScript interpretuje wyrażenia logiczne. Konkretnie chodzi o tzw. "krótkie spięcie" (eng. short circuit).

Mianowicie przy założeniu, że x = 2 w przypadku wyrażenia:
x === 1 && y === 2;
zostanie sprawdzony tylko pierwszy warunek, ponieważ drugi nie będzie miał znaczenia. Wynika to z faktu, że całe wyrażenie będzie prawdziwe tylko wtedy, jeżeli faktycznie x = 1 oraz y = 2; W tym przypadku tak nie jest i wiemy to już po weryfikacji pierwszego porównania.

No i teraz mając tę wiedzę, wiemy że takie wyrażenie:
x && (x = 2)
oznacza, że jeżeli X jest wartością prawdziwą, to zostanie wykonana druga część wyrażenia, będąca w tym przypadku przypisaniem wartości 2 do x.

Inaczej mówiąc: jeżeli x nie jest wartością "falsy" zostanie wykonane wyrażenie znajdujące się po prawej stronie operatora && i dojdzie do przypisania. W przeciwnym razie druga część wyrażenia zostanie pominięta.

Jednocześnie zapis:
x && (x = 2) można zapisać również jako
x &&= 2;

I to właśnie jest logiczny operator przypisania. Analogicznie można wykorzystać operatory:

x ||= 2; (wartość zostanie przypisana tylko wtedy, gdy x jest wartością falsy)

x ??= 2; (wartość zostanie przypisana tylko wtedy, gdy x jest wartością null lub undefined – ponieważ wykorzystujemy tutaj nullish coalescing)

Także tak jak widać, logiczne operatory przypisania ułatwiają przypisywanie wartości w zależności gdy podany warunek jest spełniony. Najważniejsze w ich zrozumieniu jest pamiętanie o zasadzie "short circuit" oraz tym jak działają operatory AND, OR oraz nullish coalescing.

Podsumowanie

Zmiany w ES2021 z pewnością nie są przełomowe ale też bez wątpienia prywatne właściwości i metody klas czy logiczne operatory przypisania, szybko pojawią się w kodzie wykorzystywanym przez nas w codziennej pracy.

Tutaj warto zaznaczyć, że aktualnie zarówno wsparcie przeglądarek (wyłączając IE) i nopde.js (od wersji 15+) wygląda bardzo dobrze. W przypadku konieczności wsparcia starszych wersji przeglądarek lub node.js, konieczne będzie zapewnienie polyfilli lub zrezygnowanie z tych funkcji.

Mam nadzieję, że powyższy wpis nauczył Cię czegoś nowego i ta wiedza przyda Ci się w pracy. Na temat wyżej omówionych zmian ES2021 wkrótce pojawi się również warsztat na eduweb.pl, podczas którego wyjaśniam ich działanie w praktyce.

Wspaniałego dnia,
Adam

Lista linków z Newslettera:

UDOSTĘPNIJ ARTYKUŁ:

Powiązane artykuły

Programowanie i WWW

Tailwind to rewolucja, jeśli…

Tailwind CSS na przełomie ostatniego roku zdobywa coraz większą popularność. W dużym stopniu jest to w pełni zasłużone. Projektowanie interfejsów z jego pomocą jest wygodne. W dodatku…

Programowanie i WWW

Proces rekrutacji w IT z różnych perspektyw

Podczas ostatnich konsultacji Full-Stack Dev Q&A padło kilka pytań o proces rekrutacyjny. Ze względu na pozytywny feedback oraz zwrócenie uwagi na istotę tego tematu, pomyślałem że zbiorę…

Programowanie i WWW

„Coś poszło nie tak”, czyli obsługa błędów na kolanie

Błędy się zdarzają. Każdemu. I podczas gdy te dotyczące logiki biznesowej lub stabilności aplikacji możemy eliminować, tak tych związanych z interakcją użytkownika nie powinniśmy ignorować. Z jakiegoś…

Pozostań na bieżąco!

Już nigdy nie przegapisz ważnych informacji, promocji oraz nowych kursów. Zapisz się na newsletter już teraz!

Zapisując się do newslettera akceptujesz naszą politykę prywatności