Nowy Standard JavaScript
10 godz. 43 min · JavaScript · Full-stack i Programowanie
Piotr PalarzWeb DeveloperNa początku dowiesz się jakie nowości pojawiły się w języku, jeśli chodzi o tworzenie zmiennych i stałych. Poznasz dwa nowe słowa let i const, a także dokładnie omówimy ich różnice, względem znanego nam do tej pory słowa var. Następnie poruszymy temat obiektów. Zobaczysz jak nowy zapis pozwoli znaczenie ułatwić nam pracę i sprawić, by kod był bardziej czytelny. W kolejnym rozdziale porozmawiamy o zmianach w funkcjach. Poznasz tzw. arrow functions wraz z poradami, kiedy z nich korzystać, a także z konsekwencjami ich użycia. Zobaczysz również, jak korzystać z domyślnych parametrów. Następną nowością będą operatory rest i spread, które znacząco uproszczą pisanie kodu dla funkcji i tablic. Chwilę później rzucimy okiem na bardzo ciekawy temat, mianowicie na tzw. destructuring. To nowa funkcja języka, która pozwala w łatwy sposób wyciągnąć odpowiednie dane z tablic i obiektów, nawet jeżeli te posiadają kilkupoziomową, zagnieżdżoną strukturę. Zmian doczekały się również ciągi znaków. Poznasz nowy zapis, tzw. template string, a także możliwość wykorzystania funkcji tagujących.
ES6 wprowadza do języka JavaScript zapis klas. I choć na początku wydaje się, że to duży krok w stronę klasycznych obiektowych języków programowania, to jak się przekonasz, jest to w dużej mierze tzw. syntactic sugar, a więc zupełnie nowy, prostszy zapis, a prawie identyczne jak wcześniej działanie, oparte na dziedziczeniu prototypowym. W kursie poruszymy również temat Symboli oraz tego jak z nimi pracować, a chwilę później poznasz iteratory. To konstrukcje ułatwiające iterację, które znacząco upraszczają pracę z kolekcjami danych. Wraz z iteratorami poznasz również generatory, które ułatwiają z kolei tworzenie tych iteratorów. Istotną nowością w ES6 są również natywne Promise. To sposób na rozwiązanie problemu asynchroniczności, który znamy od bardzo dawna w postaci różnych bibliotek. Od teraz jednak Promisy znajdują się bezpośrednio w języku. Nowymi konstrukcjami, które pozwalają pracować z kolekcjami danych, są Map i Set. Dowiesz się jak z nich korzystać, a także do czego są przydatne. W jednym z rozdziałów rzucimy też okiem na tzw. Proxy API. To mechanizm języka, który pozwala na dość niskopoziomowy dostęp do różnych operacji. I choć być może nie jest to coś, z czego będziesz korzystał nad wyraz często, to warto wiedzieć, jakie są nowe możliwości tego API.
Jedną z najlepszych nowości, która zawitała do języka JavaScript wraz z ES6 są moduły. To możliwość dzielenia kodu na wiele plików, z których można pewne wartości wyeksportować, a następnie zaimportować je w innych modułach. Tutaj dowiesz się wszystkiego, co z modułami związane. Zobaczysz wiele sposobów na eksport i import, a także jak pracować z modułami w przeglądarkach internetowych. Kurs skupia się na omówieniu wszystkich najważniejszych nowości w ES6, dzieląc je na rozdziały. Jeden z nich natomiast, poświęcony został omówieniu mniejszych zmian, które znalazły się w specyfikacji. Poznasz w nim np. nowe metody tablic czy ulepszoną współpracę z Unicode.
Specyfikacja EcmaScript 2015 wprowadziła naprawdę bardzo wiele zmian, ale jej twórcy założyli, że od tego czasu każda kolejna wersja specyfikacji będzie pojawiać się co roku. Oznacza to przede wszystkim, że nie będziemy na raz bombardowani aż tak wieloma zmianami, jak w 2015 roku. W tym kursie nie zabrakło zatem omówienia nowości ze specyfikacji ES2016 oraz 2017, gdzie poznasz np. nowe metody dla stringów czy funkcje asynchroniczne.
Kiedy będziesz już uzbrojony w solidną wiedzę z zakresu nowości w ES6, dowiesz się jak w praktyce pracuje się dzisiaj z tym standardem. W jednym z rozdziałów omówimy nowoczesny workflow z użyciem npm i wykorzystamy popularne narzędzie webpack, do pracy z modułami, a także do transpilowania kodu ES6 do wersji ES5. Dzięki temu nowoczesny kod, który napiszemy, będzie mógł być uruchamiany również w starszych przeglądarkach, które nie wspierają najnowszego standardu. Dowiesz się na co zwrócić uwagę, by wszystko działało bez zarzutu.
Zwieńczeniem tego kursu będzie praktyczny projekt, w którym od podstaw wykonamy swoją własną bibliotekę do pracy z Obiektowym Modelem Dokumentu. Będzie ona w działaniu nieco podobna do znanej chyba wszystkim biblioteki jQuery. Na tym przykładzie postaramy się wykorzystać jak najwięcej wiedzy z zakresu ES6 zdobytej wcześniej. Stworzymy metody do pracy z drzewem dokumentu, a więc do wyszukiwania elementów, do tworzenia nowych, do przypisywania im klas, atrybutów czy styli CSS. Nie zabraknie również modułu odpowiedzialnego za współpracę z Ajax. Cały kod utworzymy oczywiście w sposób modułowy, aby bibliotekę można było łatwo rozwijać w przyszłości. Na koniec projekt ten przetranspilujemy do kodu ES5 z użyciem Babel i przetestujemy w starszej przeglądarce Internet Explorer 11, aby upewnić się, że nasza biblioteka działa poprawnie.
Kurs ten jest dla wszystkich osób, które znają już język JavaScript i czują się w pracy z nim swobodnie. Jeśli zatem chciałbyś pracować z nowoczesnym kodem JavaScript, to ten kurs jest zdecydowanie dla Ciebie. A może masz zamiar poznać framework Angular lub bibliotekę React? Tam również wykorzystywany jest najnowszy zapis ES6, więc wiedza ta będzie naprawdę pomocna. Z solidną wiedzą z zakresu EcmaScript 6, bez trudu pozostaniesz na bieżąco z każdą kolejną edycją tej specyfikacji.
W przypadku set mieliśmy jego odpowiednik, który nazywał się WeakSet i pamiętasz,
że on działał tak, że jeżeli utraciliśmy referencję do jakiegoś obiektu i garbage collector mógł
go usunąć to usuwał go również takiego WeakSet'u i w przypadku map mamy
również jej odpowiednik, który nazywa się WeakMap i działa w bardzo podobny sposób. Także
również te wartości, do których utracimy referencje będą usuwane i teraz
próbujemy sobie utworzyć właśnie nową WeakMap'ę. Napiszę let
na przykład age i tutaj mamy nowy konstruktor, który nazywa się WeakMap.
Możemy do niego dodawać elementy za pomocą set. Podobnie jak w poprzedniej
lekcji do zwykłego map. Natomiast możemy również dodać je tutaj od razu, tworząc
taki obiekt, podając jakiś iterable, na przykład tablice, w której będą tablice,
tak jak w lekcji poprzedniej. Na przykład person 1 i jakiś
wiek 32 i w kolejnej kluczem będzie person 2, wiek
na przykład 22. No i teraz tutaj znowu to nie jest iterator,
nie możemy sprawdzić ile elementów jest w takiej WeakMap'ie, ale mamy dostępne
metody, a jest to set, get, has oraz
delete. Czyli możemy jakieś wartości ustawiać, pobierać, sprawdzać
czy tam są albo usuwać. Zobaczmy zatem w przeglądarce, co będziemy
mieli teraz pod age, przeglądarka pokaże nam taką właśnie WeakMapę, ale
spróbujmy utracić referencje do któregoś obiektu. Na przykład person 1 null i sprawdźmy
raz jeszcze co mamy pod s. W zasadzie pod
age, tak nazywaliśmy tą zmienną. Jak widzisz, teraz nie mamy już tamtego
jednego obiektu, bo garbage collector go usunął. Skoro do person 1 nie mam już dostępu,
to można go usunąć. No i tutaj znowu rodzi się pytanie jakie byłoby praktyczne
zastosowanie takiego właśnie zapisu, czyli WeakMap i o
ile pokazałem ci w przypadku WeakSet'u, że możemy sobie do klasy to
dodać w pewien sposób, aby nie można było wykonywać metody na obiektach
nie utworzonych z tej klasy, czyli pożyczać tych metod. To tutaj możemy z kolei zrobić
sobie rzecz jeszcze lepszą, bo możemy dodać prywatność do klasy i
pokażę ci teraz jak moglibyśmy to zrobić. Przejdźmy sobie niżej i będę
chciał utworzyć sobie funkcję person i tutaj
zrobię funkcję anonimową, która od razu się wywoła, w ten oto sposób. A to
oznacza, że to co tutaj zwrócę, chociaż to dziwnie wygląda, ale
to co tutaj zwrócę będzie pod person, czyli tutaj na dole pod person miałbym jedynkę. Zatem
ja chcę tutaj mieć jakąś klasę, dlatego będę chciał zwrócić klasę, return class
Person. Mogę ją drugi raz nazwać tak samo, czyli
pod Person na pewno będzie jakaś klasa, ale po to stworzyłem funkcję oplatającą to
wszystko, żeby tutaj móc sobie utworzyć nowy zakres zmiennych i w
tym nowym zakresie będę chciał za pomocą const utworzyć stałą privateData
i utworzymy sobie właśnie nową WeakMapę. Czyli mamy
taką WeakMapę, do której nikt z zewnątrz nie ma dostępu, bo oplotłem ją taką funkcją,
którą raz się wywoła. Natomiast zwrócona klasa jest definiowana
w tym miejscu, więc wszystkie jej metody tutaj dostęp mieć będą. Zatem
do takiej klasy chciałbym sobie dodać konstruktor. To co już znamy,
dodamy sobie firstName i lastName i będziemy chcieli do this to przypisać,
ale normalnie byśmy właśnie przypisali do this. Sprawdźmy jak by to wyglądało i dodamy
sobie jeszcze metodę sayHello, którą też już znamy i ona by normalnie zwracała
taki template string, w którym mielibyśmy this firstName,
spacja, this lastName.
Zobaczmy co tutaj się w ogóle wydarzy. Widzę,
że chyba ma jakieś błędy w tym miejscu. Okej, widzę że tutaj powinniśmy
te wartości przypisać i this lastName
również i tutaj pojawił mi się jeszcze jeden błąd w tym miejscu
konkretnie. Tak to powinno wyglądać, tutaj zakończymy sobie średnikiem,
okej. No i teraz spróbujmy utworzyć sobie nowy obiekt, który nazwiemy sobie person 3
i będzie to new Person, czyli ta funkcja kiedy
się wywołała, zwróciła nam person, która jest dostępna tutaj, więc jeżeli napiszę new Person
Jan Kowalski, to
będziemy mogli zrobić console.log person 3, na przykład firstName. Mamy
do tego dostęp, bo jest to przypisane bezpośrednio do obiektu. Zobaczmy. Widzimy
Jan i jeśli bym zrobił person 3 sayHello, to
będziemy widzieli Jan Kowalski. No ale właśnie dlatego tutaj mówię, że brakuje nam w JavaScripcie
prywatności, bo cały czas mam dostęp do person 3, na przykład lastName. Mogę
je również zmienić. Teraz ci pokażę jak możemy je zrobić jako
prywatne, czyli aby one nie były widoczne. Zamiast przypisywać je w konstruktorze bezpośrednio
do obiektu, zróbmy tak, że odwołamy się do privateData. Następnie
set i pod this, a this to jest nasz obiekt. Widziałeś
już, że w przypadku właśnie mapy możemy przypisywać do niej pod
kluczem obiektu jakieś dane, czyli kluczem będzie ten obiekt this, a danymi
będzie coś takiego firstName i tutaj mógłbym napisać drugi
raz firstName, ale pewnie pamiętasz ten skrócony zapis obiektów. Jeżeli mamy się powtarzać, to
wystarczy, że napiszemy to raz, więc chcę tutaj utworzyć obiekt, który będzie przechowywane
w tej WeakMap'ie pod this, a do niej nikt nie ma dostępu z zewnątrz,
bo jest zawarta w funkcji i chcę żeby ten obiekt przechowywał te przekazane tutaj wartości
i teraz w sayHello będziemy
chcieli zwrócić, najpierw zapisując sobie w zmiennej może data, privateData,
get i podam this, czyli jeżeli podam obiekt
do WeakMap'y, to zostanie dla mnie zwrócone to co pod tym obiektem, czyli pod this
zostało zapisane, a więc taki oto obiekt. Zauważ, że właśnie te dane nie są przypisane
bezpośrednio do obiektu, tylko są w WeakMap'ie pod kluczem tego obiektu. Będę
to miał teraz w data i tutaj będę mógł zwrócić w taki oto sposób. Zobaczymy
jak to zadziała i może tutaj sobie w console.log jeszcze zróbmy person 3 sayHello. Odświeżam,
zobaczymy tutaj, że po pierwsze mamy undefined. Czyli nie można się już odwołać do
persona 3 firstName, bo ten obiekt nigdzie nie ma, poprzez this przypisane właśnie
tych właściwości. Kiedy jednak odwołamy się do sayHello, to widzimy, że wszystko jest
okej, bo metoda sayHello dodana na prototypie tutaj this ma dynamiczne,
ale wrzuca sobie to this do privateData, czyli do tego WeakMap i dostaje
z powrotem obiekt, który tutaj przy tworzeniu tego obiektu został utworzony, więc
jak widzisz, możemy sobie tutaj stworzyć taką prywatność, bo nikt do tej WeakMapy nie
ma dostępu, a więc nie może tam przekazać żadnego obiektu. Gdyby ona była na zewnątrz,
to wtedy mógłbym napisać privateData get i przekazać person 3. To
by było dokładnie to samo, co wewnątrz tutaj this, ale że nie jest na zewnątrz, to nikt
nie może tego zrobić. No i teraz ostatnia rzecz. Dlaczego plusem jest,
że nie jest to zwykła mapa, ale WeakMapa. No właśnie z tego powodu, że jeżeli teraz byśmy
napisali persona 3 równa się null, to znaczy, że znowu straciłem
odwołanie do tego nowoutworzonego obiektu. Nigdzie indziej go sobie nie przekazałem i
nie zapisałem, to on może zostać usunięty, a razem z nim w
tej WeakMap'ie może zostać usunięty ten obiekt, który przechowywał jego
dane. Dlatego, że jeżeli to co jest pod kluczem zostanie usunięte, to
dane również mogą być usunięte i znowu w przypadku WeakMap'y kluczem
może być tak jak w przypadku WeakSet'u wyłącznie obiekt. Nie może to być wartość
prymitywna. Jak zatem widzisz, to są te cztery nowości, czyli Set, WeakSet,
Map oraz WeakMap i myślę, że szczególnie zwykły Set, a także Mapa
i WeakMapa będą często wykorzystywane i są to naprawdę mile
widziane dodatki do tego co już mieliśmy w języku JavaScript, więc teraz jeżeli
będziesz chciał przechowywać jakieś dowolne pary klucz, wartość, to
zamiast zrobić to w zwykłym obiekcie, lepiej utworzyć sobie mapę i plusem mapy jest
również to, że można jako klucza używać obiektu, aby na przykład dodać
do niego jakieś nowe dane. Takim obiektem może być oczywiście na przykład
znalezione w drzewie dokumentu element jakiś html, do którego chcesz coś
dopisać, właśnie poprzez taką Mapę.