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 jeszcze jedną ciekawą rzecz, która została ustandaryzowana
w przypadku ES6. Jest to nazywanie funkcji. Teraz
po co nam jest potrzebne coś takiego. Otóż mam tutaj utworzoną zwykłą funkcję,
taką którą znamy jeszcze z ES5 o nazwie getName i teraz
ta nazwa jest dostępna po odwołaniu się do takiej funkcji,
czyli na przykład getName kropka name. Każda
funkcja coś takiego mieć powinna i to nam zwraca zawsze string z nazwą takiej funkcji
i mógłbyś się zapytać po co mi jest potrzebny taki string. No i powiem ci szczerze, że
on jest najbardziej potrzebny w sytuacjach debugowania. Gdyby nasza funkcja
z jakiegokolwiek powodu zwracała błąd, który mogę zasymulować za pomocą throw
new error, to zobaczmy co się pojawi po wywołaniu takiej funkcji,
czyli zerknijmy, funkcja się nazywa getName. Wywołuje
ją i mamy błąd, ale co jest ciekawe w tym tak zwanym stosie,
czyli stack trace pokazuje nam się, że ten błąd wystąpił at
get name. Tutaj jest nazwa tej funkcji. Natomiast jeżeli mamy same funkcje
anonimowe, to bardzo trudno zobaczyć w takich logach błędów gdzie jakiś błąd
się pojawił. Szczególnie na przykład w środowisku Note.js, gdzie często wysypują się
błędy i mamy mnóstwo takich linijek i trudno naprawdę jest się dowiedzieć
gdzie błąd się pojawił. Jeżeli funkcja jest nazywana, wtedy tego problemu nie
ma. Natomiast mógłbyś zapytać kiedy jest problem. No właśnie wtedy, kiedy funkcje
są anonimowe i nie mają właściwości name. Natomiast ES6
można powiedzieć, że ustandaryzowało nadawanie nazw dla funkcji
i teraz powinno to działać w taki sposób, że nawet jeżeli utworzymy zmienną, która
przechowuje funkcję, to ta funkcja powinna mieć taką nazwę jaką ma
zmienna i teraz będę chciał ci to pokazać. Jeżeli byśmy sobie tę
funkcję przypisali do zmiennej za pomocą let lub var, to nie
ma to akurat znaczenia i zmienną nazwę na przykład, jak
ona się nazywała, zerknijmy getName, let get name, to
normalnie taka funkcja tutaj nie miałaby name, ale teraz jeżeli ją sobie tutaj
podejrzę, get name name, to również
została zwrócona wartość get name, czyli EcmaScript to ustandaryzowała, że nawet jeżeli
taka funkcja anonimowa jest przypisywana do zmiennej, to powinna jakby po tej zmiennej
odziedziczyć name. No i to co jest ciekawe, gdybym tu oczywiście miał inną
nazwę, na przykład funkcja name, to
name takiej funkcji, w tym przypadku byłoby to name, czyli ona wtedy ma swoją
własną nazwę, ale tylko została przypisana do zmiennej. Natomiast, jeżeli nie ma tutaj
taki nazwy to będzie ją jakby dziedziczyć tej zmiennej i teraz
nawet gdybym utworzył inną zmienną o nazwie fn i przypisał do niej getName,
żeby one obie kierowały na tę funkcję, to gdybym napisał fn
name, to cały czas będzie to getName i gdybym ją wywołał, a ona
wiesz, że wywoła błąd, to będziemy
to widzieli, że on jest w funkcji getName. Dzięki temu łatwo będzie zdebugować,
bo musimy sobie znaleźć taką funkcję getName. No i to się pojawia w tym miejscu. Co ciekawe
nie działa to tylko w przypadku tworzenia takich prostych zmiennych. Gdybym sobie utworzył
obiekt. Ja teraz go wkleje, w którym
stworzyłbym metodę, która w ten sposób wygląda, czyli na przykład byłaby to funkcja strzałkowa
albo ta skrótowa metoda, która ci już pokazywałem, czyli w taki sposób, to
sprawdźmy sobie, kiedy się odwołamy do person getName kropka name, co
nam się pokaże. Okaże się, że też
jest to getName, więc tutaj ta funkcja dziedziczy sobie
name z właściwości obiektu pod jaką została zapisana. Dzięki
temu praktycznie w każdym miejscu każda funkcja powinna mieć przepisane jakieś
name. Jest tylko jeden przypadek, kiedy nie będzie takiego name, zaraz
ci to pokażę. Ale jeszcze pokażę ci tylko jeden przykład, gdybyś
miał funkcję, którą byś utworzył za pomocą bind,
czyli mieliśmy funkcję getName tutaj u góry i bind zwraca mi nową
funkcję, pod którą, która pod this będzie miała to co tutaj przekażę. Nie to
teraz istotne, ale chodzi o to jaki tutaj będzie name, new fn, sprawdźmy
kropka name i okaże
się, że jeżeli funkcja była utworzona za pomocą metody bind, to ma tutaj
coś takiego jak bound get name. Dzięki temu również, gdybyśmy ją
wywołali, ona będzie miała błąd, to
zobaczymy at get name, czyli cały czas możemy znaleźć, w którym miejscu ten
błąd się pojawia i teraz jest tylko jeden przykład, którego raczej
nie będziesz tak wykorzystywał kiedy nie będziemy mieli przypisanej właściwości name
poprawnie. Ona będzie. Nie będzie pusta, ale nie pozwoli nam zdefiniować
do końca, o którą funkcję chodzi i to dzieje się wtedy gdybyś utworzył funkcję,
co robi się niesłychanie rzadko z użyciem konstruktora new function. On działa
tak, że tutaj jako pierwszy parametr podajemy string, z argumentami, które miałyby do takiej
funkcji wpaść, gdyby tutaj było name, to tutaj sobie też piszemy wtedy name, a jako
drugi parametr podajemy ciało funkcji w formie string'u, czyli return, na przykład Jan. Taka
funkcja zostanie zwrócona do get person name. Jeśli ją wywołam, to będzie zwracać Jan, ale
pytanie get person name. Jakie ona ma name
i okazuje się, że wtedy jest to anonymous. Natomiast tak czy siak jest to zdefiniowane. Nie jest to pusty
ciąg znaków. W ten sposób, jak widzisz, EcmaScript ustandaryzowała, że
zawsze tylko jeśli jest to możliwe name powinno być w jakikolwiek sposób
przypisane do funkcji. Nawet jeśli ją utworzymy jako funkcję anonimową
tak jak tutaj, przypisaną po prostu do zmiennej i to pomaga nam między
innymi przy debugowaniu, kiedy w takich funkcjach pojawiają się błędy.