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 możemy korzystać ze słowa super nie tylko w
klasach. Do tej pory widziałeś, że korzystamy z super w konstruktorze klasy pochodnej. Jeżeli
dziedziczymy z innej klasy, ale także, że możemy w którejś z metod wykorzystać super
kropka nazwa metody i w ten sposób odwołujemy się do metody na prototypie klasy
nadrzędnej, gdzie też jest odpowiednio ustawione. Natomiast z
słowa super możemy skorzystać również w przypadku obiektów. Zauważ, że mamy
prostą klasę Person, która ma metodę sayHello i ta metoda zwraca
this firstName i this lastName. Tak naprawdę jej nie interesuje, co
to jest this dlatego, że to this możemy w odpowiedni sposób ustawić i było
tak na przykład przy dziedziczeniu. Kiedy dziedziczyliśmy, to klasa pochodna miała
swoje this, które było odpowiednio tutaj ustawiane. Natomiast teraz nie mam klasy pochodnej,
ale mam zwyczajny obiekt, który też ma firstName i lastName oraz
position. Chciałbym, żeby ten obiekt mógł skorzystać z metody sayHello.
Jak byśmy musieli to zrobić? Otóż musielibyśmy tutaj
dodać sobie własną metodę zasadzie, bo w zasadzie chciałbym dodać metodę sayHello własną,
która będzie wewnątrz wykorzystywała metodę sayHello, która jest
tutaj. Inaczej oczywiście moglibyśmy się odwołać do person sayHello czy
w zasadzie tutaj najpierw prototype, sayHello
i wiemy, że możemy zrobić call przekazując employee1. Ten
zapis już znasz, więc ta funkcja wtedy będzie wywołana, gdzie this ustawimy na employee1.
No więc zwróci nam to, co nas interesuje, gdybyśmy to byśmy to zrobili w console.log'u.
Zobaczmy. Jan Kowalski. Natomiast ja bym chciał
tutaj utworzyć sobie własną metodę sayHello. Skorzystamy
tutaj z tego skróconego zapisu, który też już poznałeś i chciałbym, żeby ona nam wracała
coś, co widzieliśmy już w przypadku dziedziczenia wcześniej. Chciałbym napisać return
i tutaj żebyśmy mieli na przykład nazywam
się. Chciałbym się jakoś odwołać do klasy nadrzędnej, więc sobie
zaraz to uzupełnimy. Postawię sobie tutaj coś takiego albo może
coś w tym stylu i pracuję jako i
tutaj byśmy sobie dodali this position, okej. Czyli teraz
jeżeli sobie to wykomentuje, a skorzystamy z console.log i napiszemy employee
sayHello. Okej,
to mamy jakiś błąd zerknijmy gdzie on się pojawił. Tutaj
nie postawiłem przecinka, okej. No i widzimy nazywam się AAA i pracuję
jako programista. Natomiast tutaj teraz chodzi o to jak w tym miejscu podstawić to,
co nam zwróci metoda sayHello z tej oto klasy. Nie chce, jak
tutaj widzisz tworzyć jakieś nowej klasy pochodnej, ale wyłącznie dla jednego obiektu pożyczyć
sobie taką metodę. Mógłbym zatem skorzystać z takiego zapisu jak jest tutaj wewnątrz
tej funkcji i później to podstawić, ale możemy zrobić jeszcze inaczej. Przy metodach obiektów,
w jednej z lekcji pokazywałem ci, że mamy metodę setPrototypeOf, czyli mógłbym
teraz dla tego obiektu napisać Object setPrototypeOf
i tutaj podajemy obiekt employee, że
chce żeby jego prototypem było to, co mamy pod person prototype. Cały
czas pamiętaj, że chociaż utworzyliśmy ten zapis z klas, to normalnie mamy tam cały
czas prototyp, tak samo jak byśmy to utworzyli z użyciem function. W ten
sposób ten obiekt normalnie jego prototypem było od razu Object kropka
prototype, a teraz będzie to person prototype, a dopiero później Object prototype,
jakby o jeden poziom wyżej kiedy mamy już coś takiego ustawione, moglibyśmy
sobie tutaj stworzyć zmienną gdzie byśmy napisali name i skorzystalibyśmy z Object getPrototypeOf,
żeby to wszystko było dynamiczne,
ta metoda, jeżeli przekażemy jakiś obiekt, to zwróci nam jego prototyp,
czyli jeżeli napisze this, this będzie całym tym obiektem, to zostanie
mi zwrócony person prototype. Na tym miałbym metodę sayHello
i wywołałbym ją z użyciem call, czyli
to, co zrobiłem niżej i podałbym this, czyli w ten cały zapis
zwraca mi prototyp, czyli person prototype. Na nim jest metoda sayHello,
którą mogę wywołać mówiąc co ma być pod this i ona mi wtedy zwróci this firstName i this lastName
biorąc je sobie tutaj z tego obiektu i teraz tutaj gdzie mieliśmy to AAA, mógłbym
podstawić name. Zobaczymy czy ma to sens. Okazuje
się, że jak najbardziej. Natomiast i ten zapis można sobie uprościć, skorzystając
czy korzystając ze słowa kluczowego super. Wykomentuję
sobie zatem tę linijkę i w miejscu gdzie zrobiłem name wystarczy, że napiszę
super i następnie metodę sayHello. Zobacz
o ile to jest prostsze. Czyli to co jest niesłychanie ważne to z super można korzystać
z zewnątrz funkcji w obiektach. Nie musi to być klasa. Natomiast taki obiekt
musi mieć ustawiony jakieś prototyp, czyli innymi słowy gdyby nie miał tutaj
ustawionego prototypu nie powinno być błędu, ale wtedy będzie sayHello wyszukiwane na prototypie
Object kropka prototype. Natomiast jeżeli mu ustawiłem na person prototype,
to tam będzie to szukane i super jest dynamiczne dlatego, że wystarczy,
że wywołam super sayHello. Interpreter od razu znajdzie sobie metodę
sayHello, która jest tutaj. Ustawi odpowiednie this na ten właśnie obiekt, no
i zwróci mi poprawne dane. Zobaczmy czy jest efekt ten sam. Oczywiście tak,
więc możesz w ten sposób sobie pożyczyć czy wykonać metodę z
prototypu. Jeżeli dla obiektu jakiegoś ustawisz prototyp, a zauważ
że to nie jest żadna klasa, w której z czegoś dziedziczyliśmy, to możesz za pomocą
super odwołać się do metody jakiejś klasy nadrzędnej, z
której prototypu dziedziczysz. Ostatnia uwaga jest taka, że nie możesz
tutaj zapisać funkcji w taki normalny sposób. Pokazywałem ci w lekcji o
tych nowościach w literałach obiektów, że można zapisywać te
skrócone funkcje i że w zasadzie działają one tak samo. Tutaj jest taka różnica, że super
nie zadziała na zwykłej funkcji. Widzisz, że generuje to błąd. Podobnie nie zadziała
to gdybym tutaj sobie stworzył funkcję typu arrow, czyli strzałkową, też nie
będzie to działać. Zobaczmy, ponownie mamy błąd, czyli to zadziała wyłącznie
jeżeli korzystamy ze skróconego zapisu dla funkcji. No i
widząc jak to wygląda może jeszcze tylko, żeby pokazać ci, że ten przykład może być
bardziej praktyczny, dodajmy sobie metodą statyczną do klasy Person.
Więc wiesz już jak takie metody dodawać. Napiszmy static na przykład inherit i chciałbym
żeby ona przyjmowała jakiś obiekt i chcielibyśmy tutaj generalnie
zrobić sobie dziedziczenie, już ci pokażę w jaki sposób. Może łatwiej będzie najpierw to wywołać,
czyli zamiast pisać coś takiego, to chciałbym się odwołać do Person, czyli
do naszej klasy, do metody statycznej inherit, którą utworzyłem i chciałbym
ją wywołać z employee. Dzięki temu ten prototyp byłby ustawiony,
więc to co mieliśmy w tym miejscu możemy sobie skopiować. Napiszemy return
Object setPrototypeOf i tutaj przekażemy
ten parametr oczywiście na Person prototype, czyli w tym momencie jeżeli skorzystamy
już takiej fajnej ładnej metody person inherit i przekażemy jakiś obiekt, to
ten obiekt od teraz będzie sobie dziedziczył z tej klasy i mimo tego, że nie tworzyliśmy
nowej klasy pochodnej, a to wszystko powinna działać poprawnie. Zobaczymy. No
i efekt jest dokładnie taki sam. Jak zatem widzisz w taki prosty sposób możesz
nie tworząc nowej klasy pochodnej dla danego obiektu na moment włączyć
mu dziedziczenie. W zasadzie mówię na moment, bo możnaby było to z powrotem później przestawić, aczkolwiek
zazwyczaj nie będzie to miało sensu, ale dzięki temu mamy obiekty już
gotowe, już utworzone i możemy z pomocą na przykład takiej prostej metody
statycznej pozwolić im dziedziczyć z jakiejś klasy.