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, jak możemy dodać iterator do klasy, czyli klasy możemy traktować jako
swój nowy typ w JavaScripcie. Możemy sobie jakiś swój własny typ utworzyć, on
ma własne metody, jakieś właściwości i pokażę ci teraz jak możemy iterator do
tego dodać i również jak jest z tego będą korzyści. Ja już otworzyłem trochę kodu,
nie przestrasz się, bo nie jest on skomplikowany. Zobacz że będziemy mieli pewnego rodzaju klasę
model, która w konstruktorze przyjmuje jakiś obiekt, czyli tutaj dowolny obiekt możemy
przekazać, który ma powiedzmy firstName, lastName i tak dalej, co tylko chcemy i zostanie
to zapisane pod this data, a następnie każdy taki nowoutworzony obiekt, jeżeli z
new model go utworzymy, będzie miał metodę get, która pozwoli nam wybrać
jakieś dane. Jeżeli napiszemy kropka get firstName, no to z tego data to zwrócimy, a set
pozwoli nam to ustawić, czyli tutaj nie ma nic skomplikowanego w razie czego na spokojnie sobie
to przejrzyj i zrobiłem drugą klasę Collection, troszkę bardziej skomplikowaną,
ale też nie jest jakaś trudna. Otóż, jeżeli stworzymy sobie new Collection to
będziemy mogli przekazać od razu jakieś modele, tutaj do konstruktora, utworzymy
w tym new Collection pustą tablicę i następnie sprawdzimy czy te przekazane modelem
mają iterator. Przejdziemy zaraz do tego. Jeżeli mają iterator, to przekażemy
je do metody populate, a ta metoda, zauważ, że pętla
for of, która wymaga iteratora, dlatego sprawdziłem czy te modele mają iterator, pętlą
for of przeiteruje po wszystkich przekazanych modelach i każdy
z nich doda do tablicy models, tworząc z niego po prostu nowy model, czyli
new model i tutaj przekażę jeden taki obiekt, jakiego tutaj oczekuje. Natomiast
stworzyłem sobie metodę has iterator. Zauważ, że jest to metoda statyczna,
o czym też się już uczyłeś, dostępna na Collection i jeżeli przekażę
dowolną rzecz, to chcę sprawdzić czy ta rzecz zawiera iterator, więc łatwo to sprawdzić, po
pierwsze sprawdzam czy w ogóle coś zostało przekazane i jeżeli tak to sprawdzam czy typeof
tego obiektu, symbol iterator czy to jest funkcja, czyli
czy pod symbol kropka iterator znajduje się funkcja. Jeżeli tak, to znaczy, że dany obiekt
ma iterator. No i taką właśnie metodę sobie utworzyłem i jeszcze
jedna rzecz, którą tutaj mamy. Jest to stała users i tutaj odwołujemy
się do windows, window users. Zauważ, że tutaj w pliku HTML dodałem
sobie skrypt właśnie windows users i mamy od razu jakiś użytkowników i zrobiłem
tutaj żeby nie zaśmiecać naszego kodu JavaScript'owego, więc pod users
będziemy mieli jakiś użytkowników i możemy to podejrzeć konsoli, wpisując
po prostu users i zauważ, mamy jakieś obiekty. Teraz zatem
będę chciał utworzyć sobie nową kolekcję i napiszemy sobie let
users równa się new Collection i przekażę tam users. Oczywiście
mogę tutaj od razu napisać kropka, window kropka users, ale sobie to zapisałam jeszcze
w stałej, żeby mi nikt tego nie nadpisał. Prześledźmy zatem, co się
stanie. Otóż do new Collection przekazuje users. Wiemy, że jest to tablica, która
nam się tutaj wyświetliła z różnymi obiektami, więc wywołuje się konstruktor i sprawdza
czy te przekazane users jest to tablica czy zawiera w sobie iterator. Zawiera,
więc wywołajmy metodę this populate, przekazując tam wszystkie te modele.
Czyli tak naprawdę te dane, tą tablicę. Metoda populate, pętla
for of, przeiteruje przez każdy z tych elementów i na podstawie
każdego pojedynczego takiego modelu, takiego na przykład obiektu, zobacz,
on ma tutaj różne właściwości, utworzy nowy model, czyli zrobieni new Model i
zwróci nam z takiej klasy model. Zapiszemy sobie to tutaj, więc będziemy to mieli
w kolekcji. No i teraz chciałbym móc, na tym twoim typie, jak jakim
jest kolekcja, korzystać i z pętli for of i z iteratora. Zobaczmy
czy jest to możliwe, gdybym chciał sobie napisać w konsoli users. Zwróci
mi całą naszą kolekcję, natomiast gdybym chciał napisać coś w tym
stylu, utworzył nową tablicę i chce rozstrzelić users. Będziemy mieli błąd
dlatego, że nasza klasa nie zawiera w sobie symbol iterator, co tutaj widać,
dlatego możemy teraz dodać do klasy na prototypie iterator. Jest
to bardzo proste, zrobimy to w tym miejscu. Ja go od razu wkleję. Zauważ,
że możemy w klasie, już ci to pokazywałem, tworzyć sobie wyliczone właściwości. Czyli
możemy je nazwać, jak chcemy. Stąd też możemy, tak jak i w obiektach, dodać tutaj symbol
kropka iterator i taki iterator będzie dodany na prototypie takiej klasy. I
tutaj już nie ma nic, czego byś nie znał. Mieliśmy już ten przykład, tylko że mieliśmy
na sztywno wpisane numbers, a ja to zamieniłem na this models, this models
jest tablicą. No i tutaj sobie sprawdzam, po prostu, models i models. Innymi
słowy stworzyliśmy iterator, który będzie po kolei zwracał wszystkie modele z this kropka
models. Jeżeli teraz to napisze i spróbuję w przeglądarce utworzyć
nową tablicę z obiektu users. Okaże się, że nie ma problemu, będziemy mieli tablicę,
w której jest 10 obiektów model. Jak widzisz, wszystko
działa, jak należy i dodaliśmy sobie do swojej klasy iterator. Jeżeli wydaje ci to zbyt
skomplikowane, bo już na początku dałem tutaj dużo kodu, to proszę na spokojnie sobie to przejrzyj,
bo tutaj nie ma nic naprawdę skomplikowanego, a zrobiliśmy już jakieś
podwaliny pod jakiś framework, gdzie można tworzyć nowe modele i kolekcje
i można do tych modeli dodawać metody. Więc teraz chciałbym z jakiejś z tych
metod skorzystać. Chciałbym zatem przeiterować sobie po wszystkich
modelach w users i odfiltrować te, których email kończy się na kropka
biz. Zauważ, że te modele tutaj są i każdy z nich ma data i środku
na przykład ma email i nie które kończą się na biz. Jak się
dobrać do tego email. Otóż na każdym modelu zrobiłem sobie, pamiętasz, metodę
get, której mogę podać, na przykład, email i zwróci mi to co jest w tym miejscu,
a zauważ, że tutaj jest napisane model model model, bo są to obiekty właśnie
z tej klasy utworzone. Więc będziemy mogli, tak jak w lekcji poprzedniej, na naszej
kolekcji skorzystać z metody filter, która jest dostępna tylko na tablicach, tworząc
nową tablicę operatorem spread, rozstrzelając czy rozstrzeliwując
users, bo dodaliśmy iterator i następnie metodą filter już
mogę sobie filtrować. Zrobimy sobie tutaj też arrow function. Jeden
user będziemy mieli i gdybyśmy zrobili console.log, to pamiętaj, że będzie
to taki obiekt utworzony z models. Widzimy, że tak jest, więc każdy
z tego obiektu, czyli user zawiera metodę get, którą na samej
górze utworzyłem. Zatem chcemy sobie pobrać user get email. Będzie
to string i znasz już metody na stringach, takie jak na przykład EndsWith,
więc chciałbym sprawdzić czy ten string email, kończy się na biz. Jeżeli tak,
to zwrócimy ten element do nowej tablicy. Jeżeli nie, to nie. W ten
sposób odfiltruje tylko te, które mają biz i gdybym tutaj napisał biz.
No to oczywiście, moglibyśmy sobie to podejrzeć, wpiszemy
biz i będziemy mieli trzy modele, gdzie każdy z nich ma dokładnie taki email.
Okej, więc skoro sobie je odfiltrowaliśmy, to
teraz chciałbym im zamienić ten email na kropka org. Zatem
na tej zwróconej tablicy metodą for each znowu sobie wykonam arrow function. Będę
miał jednego użytkownika w formie właśnie klasy model i na górze gdybyś
zerknął utworzyłem dla każdego z nich na prototypie również metodę set. Jako
pierwszy parametr podajemy klucz, czyli email, a jako drugi wartość, więc
chcę, żeby tą wartością było dokładnie to samo co tutaj, czyli chcę pobrać email,
ale metodą replace, na string'u, zamienić kropka biz
na kropka org. Mam nadzieję, że nie jest to zbyt skomplikowane, więc
zobaczymy i może faktycznie zapiszmy sobie tutaj w biz, okej.
I teraz odświeżmy tutaj i zróbmy
biz, żeby to sprawdzić, okej. Tam
się pojawiła wartość undefined, bo for each nam nie zwraca już
tablicy, na której operowało, więc musimy to zostawić takiej formie, ale będziemy mogli sobie
teraz powiedzmy pętla for of, która też już na naszej kolekcji będzie działać. Zrobimy
let user of users i każdemu
z nich będziemy chcieli wyświetlić user get email, okej.
Zróbmy sobie to w ten sposób, to wszystko już będzie działać i zauważ, że teraz żaden z nich nie ma
emaila, który się kończy na kropka biz. Jest to taki prosty przykład, ale
pokazałem ci, że możesz stworzyć sobie dowolną klasę i dodać do niej iterator. To
co jest tutaj, jeszcze będzie można uprościć, w przypadku generatorów, o czym powiemy sobie później.
Niemniej jednak, już widzisz, że dodanie symbol kropka iterator sprawia,
że możemy na naszym typie, który utworzyliśmy później z takiej kasy na
users korzystać z operatora spread czy na przykład z operatora czy w
zasadzie z pętli for of, a dodatkowo jeżeli chcemy wypożyczyć sobie metody
tablic, to możemy w locie utworzyć tablice, gdzie wstawimy całe, cały
nasz obiekt oraz rozstrzelimy operatorem spread i wtedy wszystko działa jak należy, a nie
musimy dziedziczyć z array po to, żeby mieć metody tablic.