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.
Tą lekcją rozpoczynamy rozdział, w którym pokażę ci co zmieniło się, jeśli chodzi o funkcje
w ES6 i w tej lekcji zajmiemy się czymś co nazywa się arrow
function. Na siłę możemy to na polski przetłumaczyć jako funkcja strzałkowa, więc
pokażę ci jak ona wygląda. Na początek mamy taki oto kod, czyli utworzyłem
sobie zwykłą funkcję anonimową. Jest to tak zwane wyrażenie funkcyjne, czyli function
expression, przypisane po prostu do zmiennej. Ona może być utworzona z var czy z let, akurat
tutaj nie będzie to miało znaczenia. Jak działa let już wiesz, więc wywołanie tej funkcji zwróci
nam po prostu słowo Jan. Teraz pokażę ci jak taką funkcję przepisać
na nową tak zwaną arrow function, więc ja ją sobie wykomentuję, żebyśmy
nie mieli błędu kiedy będę chciał napisać let i od nowa zadeklarować
taką samą zmienną, więc napiszę getName i teraz napiszę coś
dziwnego i zaraz ci wytłumaczę na czym to polega. Okazuje się, że taki
zapis jak tutaj zrobiłem, czyli to co teraz podświetlę. Ta całość
jest to funkcja, która nie przyjmuje żadnych parametrów i zwraca string Jan.
Uwierz mi, że jeżeli to wykonamy, a możemy to zrobić w przeglądarce, bo
jesteśmy w tym globalnym zakresie getName. Zobaczymy
słowo Jan. Tak właśnie wygląda funkcja strzałkowa i teraz gdybyśmy
ją chcieli rozłożyć na łopatki, to możemy. Na początku jeżeli ona nie przyjmuje
żadnych parametrów, to potrzebuję takiej pary nawiasów okrągłych. Następnie
zawsze musi tutaj być taka strzałka i później mamy jakieś wyrażenie
JavaScript'owe i teraz jeżeli tutaj będzie takie proste wyrażenie JavaScript'owe,
które możemy jakby w jednej linijce zawrzeć, to wtedy od razu to jest traktowane
jako return, czyli ta funkcja od razu tę wartość zwraca. Oczywiście gdybym tu napisał napisał dwa
plus dwa, ona by zwracała cztery. Natomiast, jeżeli chcielibyśmy zrobić
funkcję, która będzie miała swoje ciało największe, tak jak mamy to
tutaj, w ten sposób, że bym tutaj mógł napisać więcej rzeczy, to wtedy możemy
tutaj zrobić to w ten sposób. Normalnie sobie ją podzielić, ale
tym razem już byśmy musieli napisać słowo return. Wtedy to nie zostanie automatycznie zwrócone. Teraz
ta funkcja będzie działać dokładnie tak samo jak wyżej, ale mogę w niej mieć już różne inne
instrukcje i może ja cofnę do tej pierwotnej wartości i teraz pokażę
ci przykład właśnie z ES5 najpierw. Tak by
mogła funkcja wyglądać, żebyśmy to wykomentowali, czyli chciałbym, żeby ona przyjmowała jakiś
parametr. Jeżeli ona ma wartość prawdziwą, czyli true, to zwracam Jaś, jeżeli
nie, to zwracam Jan. Oczywiście to można by było zapisać krócej z tym
operatorem ternarnym, takim, ale zostawmy to w ten sposób i znowu
sobie to wykomentuje i spróbujemy utworzyć naszą zmienną pod getName
i będzie to funkcja strzałkowa, ale już przyjmująca parametr. Jeżeli
funkcja taka strzałkowa przyjmuje parametr, to możemy napisać tak jak wyżej i nazwać ten
parametr, a następnie w tym przypadku utworzymy ciało tej funkcji. Nie
musimy tworzyć tego ciała, ale chciałbym odwzorować to co jest wyżej, więc wtedy muszę to
zrobić, bo inaczej takich if'ów nie będę mógł zapisać i teraz takie if'y sobie
tutaj wrzucę i tak naprawdę ta funkcja
powinno zadziałać poprawnie. Spróbujemy ją sobie wywołać getName bez
parametru. Zwraca nam Jan, a jeżeli podam jako kid true, zwróci nam Jaś. Wszystko
jest okej. Natomiast zapamiętaj, że jeżeli będzie taka funkcja strzałkowa przyjmować
tylko jeden parametr, możesz pominąć nawiasy okrągłe, czyli w ten sposób
możesz to zapisać i też będzie okej. No i całe to wyrażenie gdybyś chciał skrócić,
to oczywiście można byłoby je zapisać tak. Wtedy słowo return nie
byłoby potrzebne. No i tutaj musielibyśmy zrobić coś takiego. Jeżeli kid
jest podane, to zwróć Jaś. Mam nadzieję, że taki
zapis znasz, bo to nie jest nic nowego dla ES6. W przeciwnym wypadku Jan.
No i znowu to wszystko, to jest poprawna funkcja, która przyjmuje parametr
nazwany jako kid, a tutaj jest ciało tej funkcji. Jest to wyrażenie, ale
od razu jakby przed tym jest słowo return. Czyli sama ta strzałka nie
mówi że coś jest zwracane. Natomiast mówi, że jakby
rozpoczyna się tam ciało tej funkcji. Zobaczmy getName i jak widzimy efekt jest taki sam.
Natomiast ja wrócę do tej postaci, która była przed momentem, żebyś widział
jak to mniej więcej wygląda, czyli taka funkcja strzałkowa może przyjmować wiele postaci. Jeżeli
nie przyjmuję parametrów, to musi mieć nawiasy okrągłe, żeby zasygnalizować, że tutaj się
zaczyna. Jeśli to ma proste wyrażenie, to on od razu jest zwracany. Jeżeli
chce mieć ciało funkcji, to robimy takie oto nawiasy klamrowe i
będzie to wtedy ciało funkcji. Dodatkowo funkcja może przyjmować parametr,
który tutaj nazywamy i jeżeli jest jeden, to nie musi być tutaj nawiasów
okrągłych. Teraz natomiast pokażę Ci jaki problem by się pojawił gdybyśmy chcieli
zwrócić literał obiektów. Gdyby miał funkcja o nazwie getObject. W zasadzie,
żeby to wyglądało tak samo to utworzylibyśmy sobie taką
zmienną, którą przechowuje funkcje i chciałbym z niej zwracać na przykład
pusty obiekt. Albo powiedzmy w obiekcie byłoby firstName Jan.
Wiem, że jest to możliwe. Nie ma najmniejszego problemu, ale jak to przepisać na
strzałkową, już ci pokażę, gdzie by się pojawił problem. Napiszmy let getObject
i tutaj chciałbym zrobić funkcje strzałkową. Nie
przyjmuje żadnych parametrów, więc tylko coś takiego i tutaj wyrażenie, że ona
coś zwraca i co jeżeli bym tutaj napisał firstName Jan. Czy
ta funkcja będzie zwracać taki literał obiektu? Czy też nie? Sprawdźmy,
getName i widzimy, że
getName nam tutaj zwróciło wartość undefind czy że w zasadzie nie jest zdefiniowany. To
nie chodziło o tą funkcje get Object. Zobaczymy czy
na pewno tak nazwałem, tak i zobacz ona zwraca undefined. Dlaczego?
Wydawałoby się, że wszystko jest okej, ale tak się nie dzieje. Otóż
ta funkcja, czyli interpreter JavaScript'u nie traktuje tych nawiasów
klamrowych jako obiektu, który powinien zwrócić, ale jako ciało tej
funkcji. Dlatego nam to nie działa, bo pokazałam ci wyżej, że właśnie tak się określa
ciało funkcji dlatego jeżeli chcesz takiej funkcji strzałkowej od razu zwracać literał
obiektu, to powinieneś go opleść jeszcze takimi oto nawiasami i
to sprawia, że wtedy to co jest wewnątrz jest wyrażeniem JavaScript'owym i takie
wyrażenia można już bez problemu zwrócić. Zobaczmy teraz getObject
i okazuje się że taki literał obiektu został zwrócony i tutaj mamy jego
dane. Pokażę ci jeszcze jedną rzecz. Mam nadzieję,
że wiesz czym jest zmienna arguments. Jeżeli sobie utworze dowolną funkcję, na
przykład nazwę ją args, to nie ma znaczenia, ale w ten standardowy sposób, to mogę
w konsoli sobie wyświetlić arguments i jest to taka specjalna zmienna
wewnątrz funkcji i teraz jeżeli wywołam funkcje args i przekaże jej na
przykład 123, to wszystkie te argumenty tutaj przekazane
wpadną pod zmienną arguments takiego obiektu, który wygląda trochę jak tablica.
Zobaczmy. Jak widzisz, one się tutaj pojawiły i oprócz tego ten
obiekt jeszcze zawiera inne właściwości, ale ma tutaj właśnie pod indeksem
0, 1 i 2, wartości przekazane kolejno do funkcji, czyli
na niej sobie możemy w jakiś sposób operować i teraz pytanie czy funkcje strzałkowe również
mają zmienną arguments. Spróbujmy sobie przepisać tą funkcję. Napiszmy
let args i chciałbym, żeby to była funkcja strzałkowa. Teraz
jest to poprawna funkcja strzałkowa. Wywołuje ją przekazując te parametry i zobaczymy
jak to będzie wyglądać. Okazuje się, że mamy błąd, arguments is not defined, czyli
wewnątrz takiej funkcji nie jest tworzona zmienna arguments. Natomiast
gdybyśmy i to jest bardzo istotne opletli tę funkcję
inną funkcją, bo arguments jako zmienna po prostu nie istnieje tutaj w tym
zakresie o jeden wyżej tej funkcji, tak można byłoby powiedzieć. Jeżeli
bym stworzył funkcję, którą nazwał getArgs i wewnątrz
utworzył taką funkcję oraz ją wywołał,
args, powiedzmy, w ten sposób i wywołałbym
getArgs. Okej,
zobaczymy. To nagle się okaże, że ona ma dostęp do zmiennej arguments,
ale nie do swojej, czyli ważne jest, że przed momentem był błąd, bo ta funkcja była na zewnątrz i
nigdzie w tym zakresie nie istniała zmienna arguments. Natomiast kiedy wywołuję tę funkcję,
to jakby w tym miejscu arguments istnieje i że chwilę niżej ta funkcja
jest definiowana, to ona ma dostęp do tego arguments, ale to nie są jej argumenty, czyli
zapamiętaj, że funkcje strzałkowe nie mają dostępu do zmiennej arguments, do
tych argumentów, które są dla niej wywoływane. Mogą mieć ewentualnie dostęp do tej
zmiennej tylko dlatego, że są wewnątrz innej funkcji, taka zmiana istnieje i teraz
na koniec mógłbyś zadać pytanie, kiedy wykorzystywać funkcje strzałkowe. Jeszcze
trochę o nich się dowiesz. Natomiast świetnym użyciem tych funkcji jest użycie
ich jako funkcji callback zawsze wtedy, kiedy potrzebujemy na przykład posortować tablice
lub coś innego z nią zrobić, więc ja tutaj wkleję sobie teraz pewien
kod. Będzie to tablica z liczbami
i później chciałbym metodą filter, która jest na tablicach dostępna, zwrócić
sobie nową tablica, która będzie miała liczby tylko większe od 20. Robimy to w
ten sposób, że podajemy funkcje callback, która będzie otrzymywała poszczególne wartości, 10, 20 i
tak dalej. Jeśli z niej jest zwrócimy true, to w nowej tablicy ten element się
znajdzie, na przykład 10. Jeżeli false, to nie. No i ja tutaj po prostu operatorem sprawdzam,
w ten sposób, tym operatorem, czy ta wartość na przykład 10 jest większa od 20. On
mi zwróci true lub false, które zwracam w tej funkcji. W ten sposób jeśli bym sobie wyświetlił
greater than 20, to zobaczymy tablice tylko z tymi liczbami. Natomiast
taki callback musimy tutaj wpisać i w tym miejscu i świetnym użyciem będzie
właśnie skorzystanie z funkcji strzałkowej. Jak byśmy to zrobili? Wytnę
sobie tylko tę wartość albo w zasadzie może to wykomentuje i skopiujemy dla
referencji, żeby to zostało później w plikach i teraz tylko ta wartość mnie interesuje.
Zauważ, że tutaj gdzie muszę podać funkcje callback, to podam
sobie po prostu funkcje strzałkową, która ma przyjmować value. Nie muszę tego oplatać nawiasami,
bo to jest jeden parametr i chcę, żeby ona zwracała value większe od 20.
Zauważ, że na pierwszy rzut oka nie wygląda to jak funkcja, ale cały ten zapis
jest to funkcja, która przyjmuje parametr value i zwraca to
co jest tutaj. Zobaczysz, że efekt jest dokładnie taki sam, a mamy dużo
mniej kodu i kiedy już się przyzwyczaisz do tej funkcji, to jest on po prostu bardziej czytelny. W tej
lekcji zatem to by było wszystko. Natomiast w kolejnych lekcjach będziemy
ten temat jeszcze kontynuować.