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 tej lekcji pokażę ci, że do generatorów można przekazywać wartości przy
każdym użyciu next. Pokazałem ci, że pętla for of czy
operator spread, one same jakby wykonują next, ale i my również możemy to zrobić, co
będę chciał ci teraz pokazać. Utworzymy sobie funkcję generatora, którą nazwę it i będzie
ona oczywiście z gwiazdką i w środku chciałbym zrobić coś takiego, let result, czyli
stworzyć sobie zmienną, w której będziemy mieli coś takiego, yield plus
number, na przykład razy 2. Bardzo
dziwnie to wygląda, ale zaraz sobie do tego przejdziemy, a później będę chciał zrobić yield result, tu
jeszcze możemy zrobić console.log, druga
linijka, żeby zobaczyć w konsoli, kiedy tak naprawdę kod dojdzie do
wykonywania tej linijki kodu i teraz jest to generator, więc musimy z
niego utworzyć iterator, wywołując funkcje it. To nam zwróci
iterator, który pamiętasz, będzie miał w sobie na przykład metodę next i
teraz jeszcze, tutaj na górze dodam sobie number, dlatego że widzisz skorzystałem z takiego parametru
i powiem ci gdzie go można przekazać. Otóż przy woływaniu tej funkcji na początku. Przekażę
sobie piątkę i ona będzie zapamiętana tutaj pod number i teraz, co się tutaj
daje stanie. Otóż nic. Żebyśmy doszli w ogóle do wykonywania kodu,
w którym jest yield, w takiej linijce, to musimy napisać iterator next.
Zróbmy
sobie to w konsoli. Żeby zobaczyć co tutaj zostanie zwrócone, okej. Widzimy,
że jest to obiekt, gdzie ma value 10 i done równa się false. Dlaczego value
to jest 10? Dlatego, że przekazałem piątkę i 5 razy
2 jest to 10, a jest yield po prostu to zwróciło. Natomiast gdybym chciał i
taki jest nasz cel. W miejscu gdzie jest yield, podstawić jakąś wartość, którą
będziemy mogli przekazać, to akurat w tym konkretnym przypadku muszę sobie to zawrzeć w takich
nawiasach, nie zawsze jest to potrzebne, tylko chodzi o to, że tutaj to yield
jakby zwróciło nam number razy dwa i na początku jeszcze plus, więc
nic tutaj się takiego nie stało, ale jeżeli tak zrobię, to zmieni się już całkowicie to
wykonanie. Jak widzisz teraz value ma wartość undefined i po co nam
jest to yield w takich dziwnych miejscach. Otóż w momencie kiedy wywołujemy next to
możemy podać jakąś wartość. Pierwsze wykonanie yield, tak
naprawdę przejdzie w to miejsce i coś nam zwróci. Nie interesuje mnie to co jest tutaj i
na razie się tym nie przejmuj, bo jeszcze będziesz widział w lekcji gdzie będzie mówić
o współpracy promise z generatorami, w jaki sposób to dokładnie działa. Tutaj
chcę tylko pokazać na szybko koncepcję. Otóż wywołamy sobie raz jeszcze
tę linijkę, ale będziemy chcieli przekazać
jakąś wartość i ja sobie tutaj przekażę dwa. Prześledźmy, co się stanie. Pierwsze
użycie, iterator next. Będzie sobie to parsować, dojdzie do tego momentu, yield i zwróci
nam to, co jest przy tym yield'zie, ale że go oplotłem takimi nawiasami, no to nie
będziemy mieli nic zwrócone. Tak jak widzieliśmy, będzie to undefined. W drugim przykładzie,
tutaj w drugiej linijce, kiedy wykorzystam iterator next i przekaże jakiś parametr,
jakąś wartość, to ona wpadnie pod yield. Zostanie tutaj podstawiona dwójka. Number
to było 5, czyli tutaj będzie 5 razy 2 jest to 10
i do tego dodamy dwójkę i dopiero to jakby zostanie zapisane w zmiennej result.
Wykona się nam console log druga linijka i yield zwróci nam cały ten wynik. Wiem,
że wygląda dziwnie, ale zobaczmy. Rzeczywiście value jest to 12 i done jest
to false. W ten sposób to wygląda. Kod, druga linijka również się
wykonał, czyli to pokazuje, że możemy do generatora za pomocą next przekazać
jakąś wartość, która wpadnie jakby w miejsce gdzie było yield. Na
razie nie wydaje się to użyteczne. Pokazałem ci tylko najprostszą koncepcję. Dlatego zróbmy
sobie troszkę bardziej zaawansowany przykład z Ajax'em, ale nie będę go w 100%
dokładnie tłumaczył dlatego, że będziemy jeszcze korzystać z promise i tam będzie
to wszystko naprawdę bardziej widoczne i lepsze w życiu. Dlatego
ja sobie wkleję tutaj funkcję, którą
nazwałem Ajax. Ona przyjmie jakiś adres URL, utworze nowy obiekt do Ajax'a
i otworzy go na tym URL'u i go zwróci, czyli jeszcze
nie przypisze żadnego zdarzenia, po prostu zwróci ten obiekt i teraz będziemy sobie chcieli
utworzyć funkcję generującą, którą nazwiemy sobie showData, więc napiszę showData i
chciałbym, żeby to był generator, więc tutaj sobie podam gwiazdkę
i przy jego wywołaniu podamy mu jakiś adres URL i teraz
chciałbym, żeby ta funkcja zachowywała się w sposób synchroniczny. Jeżeli pracowałeś
kiedykolwiek z Ajax'em, tak jak mamy tutaj, to wiesz, że będę mógł za moment przypisać zdarzenie
onload, które się wykona za jakiś czas, kiedy dane zostaną pobrane
z Internetu i dopiero wtedy wykona się funkcja callback. Ja jednak chciałbym w tym generatorze
pracować w sposób synchroniczny. Czyli napisać yield result równa się
czy let result, równa się i tutaj jest yield
Ajax i przekazać mu i URL. Chciałbym,
żeby on mi zwrócił już gotowe dane, które mogę sobie wstawić na stronę, więc napiszę
sobie document querySelector pre-35
textContent równa się result. Tutaj mamy
index html, dodamy sobie tutaj element pre-35,
jak nasz przykład i do niego będziemy chcieli to dodać. Więc wiem, że jeszcze
na razie nie ma to sensu, ale zobacz czy nie fajnie byłoby móc pracować z Ajax'em tak, że
w tej linijce mówię wyślij mi zapytanie Ajax i jak coś otrzymasz to wykonaj
dopiero drugą linijkę. Wiemy, że generatory pozwalają na pauzowanie wykonywania funkcji. Właśnie kiedy
zobaczą yield. Z tego powodu musimy utworzyć jeszcze jedną
funkcje i zapewniam cię, że później w przypadku promise będzie to prostsze, ale chcę ci na razie wytłumaczyć
koncepcję. To już będzie zwykła funkcja, którą nazwy makeRequest. Ona będzie
przyjmować adres URL i jakąś funkcję generatora. Konkretnie to
showData będzie tam przekazane. Na początek będę chciał stworzyć z generatora iterator,
więc wiem, że musimy generator wywołać i będzie on pod tym parametrem,
więc napiszmy URL, przekazując mu ten URL, bo on go tutaj oczekuje i żeby
w ogóle jakiś kod tym generatorze się wykonał, gdzie mamy yield, to będziemy musieli na
nim napisać it next. Natomiast, na
pewno pamiętasz, że kiedy wykonam it next, to zostanie z generatora coś
zwrócone i właśnie tutaj, gdzie jest yield ajax. On wywoła funkcję ajax
przekazując jej URL i pamiętaj, co ona robi. Ona zwraca obiekt xhr, więc
cały ten yield wyrzuci nam obiekt xhr, kiedy użyjemy it.next.
Dlatego ja sobie go zapisze tutaj, w ten sposób. Tylko
warto jeszcze pamiętać, że it.next zwróci nam ten obiekt, w którym jest value i done, więc
chcę się odwołać do value i to mi zwróci to co jest w tym miejscu, a w
tym miejscu będzie zwrócone xhr, to zostanie wyrzucone i funkcja zostanie zapauzowana.
No i jesteśmy w tym miejscu, w makeRequest i do tego obiektu xhr będę
chciał przypisać zdarzenie onload, czyli kiedy uda się pobrać
dane z internetu, to wtedy będziemy chcieli jeszcze sprawdzić czy xhr
status równa się 200, taki standardowy Ajax. No i
jeżeli tak i to jest niesłychanie ważne, to będziemy chcieli przejść do kolejnej
linijki w generatorze i pamiętasz jak to zrobić, na tym iteratorze napiszemy next. Natomiast
właśnie dlatego pokazałem ci ten pierwszy przykład u góry, że przy next możemy coś przekazać, bo
teraz to, co ja przekażę w tym miejscu, zostanie podstawione tutaj, przy tym yieldzie, czyli yield
nam wyrzucił i czeka kiedy wykonamy next
i coś przekażemy, to wracamy w to miejsce i podstawiamy za całe to wyrażenie. Więc
co tutaj chce podstawić. Otóż to, co zwrócił mi ajax, czyli xhr responseText. Jeżeli
pracowałeś z Ajaxem, to doskonale wiesz, co tutaj się dzieje okej i teraz
jeszcze musimy wysłać to zapytanie, czyli xhr send, w ten
sposób i teraz pozostało wywołać funkcję makeRequest, podając jej adres
URL, więc napiszmy sobie tutaj makeRequest. Adres
URL ja sobie skopiuję. Przygotowałem pod
takim adresem json, który będzie zwracany, a jako drugi parametr musimy
przekazać funkcje generatora, którą mamy tutaj, czyli showData. Na
spokojnie sobie to prześledź, zobaczysz o co chodzi. Wywołujemy makeRequest, podajemy adres
i showData. Wpadamy tutaj, tworzymy nowy generator czy wywołujemy
generator podając mówił URL. On nam zwraca iterator. Wykonujemy na nim next.
Wykonuje się yield i zwraca nam to, co jest tutaj, a tutaj przekazując URL
dalej, zostanie zwrócony obiekt xhr, dlatego pod value go mam. Przypisuje
do niego zdarzenie, że kiedy wszystko się pobierze poprawnie z internetu, to chcę dopiero
wtedy wywołać next. Kiedy wywołam next, wracamy do wykonywania tej funkcji.
Może to być nawet 10 minut później, nie ma żadnego znaczenia. Wtedy
odpauzowana zostanie ta funkcja i to przekazałem będzie tutaj, czyli będę
miał wynik właśnie tego ajax'a i dzięki temu będę mógł go wstawić na stronę
w taki sposób. A zatem w tej funkcji pracuje sposób synchroniczny, bo stworzyłem
dodatkowe funkcje. Wydaje się, że jest dużo kodu, dlatego zobaczysz
później w przypadku promise, że też będzie to znacznie uproszczone. Upewnijmy się jednak,
że to działa i po odświeżeniu widać, że dane są wczytywane i wstawione na stronie
poprawnie. Zatem z tego przykładu zapamiętaj, że możemy do generatora
przekazywać za pomocą next jakieś wartości, a za pomocą yield
one są do nas wyrzucane. Czyli mamy taką dwukierunkową komunikację, iterator,
w tym przypadku tutaj, w tym generatorze wyrzucił nam coś i czeka kiedy
wykonamy next i coś podstawimy, to wstawimy to w to miejsce. Na spokojnie
sobie zatem prześledź ten przykład. Natomiast w kolejnej lekcji pokażę ci jak możemy obsługiwać
błędy wewnątrz funkcji generatora.