w Praktyce
9 godz. 47 min · JavaScript · Full-stack i Programowanie
Piotr PalarzWeb DeveloperW pierwszym rozdziale tego kursu poznasz bardzo dokładnie koncepcje programowania zorientowanego obiektowo. W jednej z lekcji, omówimy wszystkie z nich na przykładzie pseudo-kodu, niezwiązanego bezpośrednio z językiem JavaScript. Dzięki temu zrozumiesz, jak realizowane jest programowanie obiektowe w wielu popularnych językach programowania. Dowiesz się czym jest klasa, obiekt, instancja, właściwości, metody, a także zrozumiesz takie pojęcia jak dziedziczenie, polimorfizm, abstrakcja czy enkapsulacja. Następnie przejdziemy już do języka JavaScript i do zrozumienia tego, w jaki sposób powyższe koncepcje są w nim zaimplementowane. Język ten nie jest bowiem w 100% klasycznie obiektowy, jak np. język PHP. Co jednak bardzo istotne, JavaScript implementuje tzw. dziedziczenie prototypowe, którego bardzo dogłębne zrozumienie, gwarantuje zrozumienie całego języka JavaScript. Dowiesz się zatem czym są konstruktory i jak je tworzyć, a także jak korzystać z prototypu funkcji. Dzięki temu będziemy mogli wykorzystać obiektowość do własnych celów, co później w praktycznych przykładach uczynimy.Na przestrzeni kilku lekcji zobaczysz krok po kroku, jak w języku JavaScript zaimplementować dziedziczenie wielokrotne. Taka wiedza absolutnie otwiera oczy na zależności rządzące obiektami w tym języku. Dowiesz się również jak rozszerzać wbudowane konstrukcje języka JavaScript czy Obiektowego Modelu Dokumentu, a także kiedy powinniśmy to robić. Omówimy problemy, jakie mogą się pojawiać przy korzystaniu ze słowa kluczowego this, a także sposoby ich rozwiązania. Poznasz 3 bardzo ważne metody funkcji: call, apply i bind.JavaScript ma wiele specyficznych cech, a jedną z nich są tzw. domknięcia. W jednym z rozdziałów zobaczysz, do czego one służą i kiedy powinniśmy z nich korzystać. Dopełnimy tym również wiedzę związaną z programowaniem obiektowym i tzw. prywatnością.Rozdział o obiektowości został celowo umieszczony na samym początku kursu, gdyż zrozumienie tych koncepcji pozwala patrzeć zupełnie inaczej na wszystkie pozostałe. Po tym rozdziale przejdziemy do omówienia bardzo popularnego, lekkiego formatu wymiany danych JSON. Dowiesz się jak wygląda składnia tego formatu, a także jak współpracuje on z językiem JavaScript.Następnie przejdziemy do bardzo ekscytującego tematu, jakim jest technologia AJAX. Dzięki niej możemy wysyłać zapytania do serwera i pobierać dane, bez przeładowywania witryny. Do zrozumienia AJAXa niezbędne jest jednak rozumienie działania protokołu HTTP, na którym opiera się sieć www. Z tego powodu, jedna z lekcji została w 100% poświęcona HTTP i dowiesz się z niej jak wysyłane są żądania i odpowiedzi, a także tzw. nagłówki, które będą dla nas niezwykle istotne. Chwilę później omówimy również bardzo ważne mechanizmy: Same- origin policy i CORS, które blokują możliwość wysyłania żądań AJAX do pewnych serwerów. Kiedy już będziesz rozumiał te niezwykle istotne koncepcje, przejdziemy do napisania pierwszego kodu, wysyłającego asynchroniczne żądanie do serwera. Następnie dowiesz się jak wysyłać, a także odbierać dane z serwera, umieszczać je na stronie oraz śledzić postęp zarówno wysyłania, jak i pobierania danych.W tym rozdziale na przestrzeni kilku lekcji napiszemy swoją własną bibliotekę AJAX, która pozwoli w niezwykle łatwy sposób wysyłać i odbierać dane. Skorzystamy w niej już w kolejnej lekcji, gdzie zobaczysz, jak wysłać wiadomość e-mail z użyciem AJAX i PHP po stronie serwera. Gotowy skrypt, będziesz mógł umieścić na własnej stronie internetowej. Na zakończenie tego rozdziału omówimy również dokładnie niezwykle sprytną technikę o nazwie JSONP, które pozwala wysyłać tzw. żądania “cross-origin”. Przekonasz się dlaczego taka technika powstała i jak współpraca klienta i serwera potrafi obejść zabezpieczenia przeglądarek.Kolejnym tematem omówionym w kursie będą Cookies, czyli tzw. ciasteczka. Dowiesz się czym są, w jakim celu istnieją, a także jak są ustawianie przez serwer. Co ciekawe, również z poziomu języka JavaScript będziemy mieli do nich dostęp, a zatem zobaczysz jak je ustawiać i odczytywać. Na tym etapie przyda nam się wiedza zdobyta w lekcji o protokole HTTP.W kursie znajdziesz również rozdział poświęcony w 100% wyrażeniom regularnym. To mechanizm języka, który pozwala dopasowywać tekst do definiowanych przez nas wzorców. Wyrażenia regularne potrafią być bardzo zaawansowane i odstraszać, dlatego rozłożymy je na czynniki pierwsze, byś dokładnie je zrozumiał. Na przestrzeni wielu lekcji dowiesz się jakie są specjalne symbole wykorzystywane przy wyrażeniach regularnych, czym są kwantyfikatory, kotwice czy np. grupowanie. Następnie przejdziemy do wykorzystania wyrażeń regularnych w języku JavaScript. Poznasz zarówno metody obiektu RegExp jak i te dostępne na obiekcie String. Dzięki nim będziemy mogli wyszukiwać np. adresów e- mail w podanym tekście, usuwać je lub zamieniać na coś innego. Jako praktyczny projekt, stworzymy “Antybluzgacz”. Wykorzystamy do tego celu programowanie obiektowe, a sama aplikacja będzie pozwalała filtrować wpisywany przez użytkownika tekst wiadomości i wyłapywać w nim niecenzuralne słowa. Wszystkie z nich zamienimy na przypadkową reprezentację znaków, np. $#!@%^. Ten projekt pokaże Ci nie tylko jak korzystać z wyrażeń regularnych, ale także jak profesjonalnie pracować z kodem JavaScript.W przedostatnim rozdziale tego kursu znajdziesz lekcje związane z dobrymi praktykami pracy. Omówimy tzw. “strict mode” języka JavaScript, zagadnienia związane z minifikacją i konkatenacją skryptów, sprawdzaniem poprawności pisanego kodu oraz delegacją zdarzeń DOM.Na końcu kursu znajdziesz 10 krótkich lekcji z serii Tips & Tricks, które przybliżą Ci wiele ciekawych konstrukcji języka JavaScript, a także technik na rozwiązanie różnych problemów. Zobaczysz np. jak wczytać obrazy w tle czy jak wyświetlić na pasku tytułowym witryny migające powiadomienie.Podsumowując, kurs ten jest dopełnieniem wiedzy z zakresu języka JavaScript i Obiektowego Modelu Dokumentu z kursu “JavaScript od Podstaw”. Poprzedni kurs nie jest wymagany, lecz jego przerobienie z pewnością pozwoli dużo lepiej przyswoić wiedzę z tego kursu, gdyż były one przygotowywane równocześnie. Oba te materiały, pozwolą od zera, wskoczyć na naprawdę wysoki poziom rozumienia języka, a także dobrych praktyk pisania kodu.
Do tego kursu mogą jednak przystąpić wszystkie osoby, które znają już podstawy języka HTML, CSS i JavaScript i chcą poszerzyć swoją wiedzę, a także spojrzeć zupełnie inaczej na ten język.
W tej lekcji pokażę ci w jaki sposób, możemy rozszerzać prototypy wbudowanych obiektów.
Nie jest to nic trudnego. I powiem ci, kiedy powinniśmy to robić, a kiedy nie powinniśmy.
Przejdziemy sobie od razu do kodu. Pokaże ci kod html. Mam tutaj ul z identyfikatorem list i kilka elementów li.
I teraz będę chciał zrobić rzecz następującą. Otóż znaleźć wszystkie te elementy poprzez document.querySelectorAll("#list li");
Zaznaczyłem tutaj, że jakby za naszymi plecami, interpretor JavaScript, a konkretnie w tym
przypadku DOM API, czyli obiektowy model dokumentu, tworzy dla nas new Nodelist.
My nie możemy takiego czegoś zapisać, ale tak się dzieje.
Dlaczego.
Już chciałbym ci pokazać. W konsoli, kiedy możemy sprawdzić jakiego typu jest dany obiekt,
mamy tutaj elems. Przejdźmy do konsoli, wpiszmy elems.
Ok.
Mamy tutaj tablicę, jak widzisz, z tymi elementami. Tak naprawdę nie jest to prawdziwa tablica, ale obiekt
tablicopodobny. I teraz mi bardzo zależy, abyś ten kurs oglądał od pierwszego kursu, czyli od kursu JavaScript
w praktyce. Stąd tak często do niego nawiązuje.
Mam nadzieję, że tak zrobiłeś bo tam wiele rzeczy tłumaczyłem. Tam tłumaczyłem wbudowane obiekty języka
JavaScript i próbowałem oddzielić grubą linią język Javascript od tego, co możemy za pomocą JavaScript
zrobić w przeglądarce.
Czyli od obiektowego modelu dokumentu.
I dlatego tłumaczyłem czym są obiekty, czym są tablice, czym są też konstruktora.
Natomiast mamy tutaj wiele konstruktorów, z których nie możemy korzystać, ale z nich jest jakby korzystane
za naszymi plecami m.in. Nodelist.
Jak to sprawdzić.
Jeżeli mamy elems, to ja w tym kursie już Ci pokazywałem, że jeżeli mieliśmy tablicę i chcieliśmy sprawdzić
jakiego jest ona typu, że jest to Array, albo z czego ona dziedziczy, to mogliśmy napisać Array.constructor.
Więc elems.constructor możemy napisać tak samo i zostanie dla nas zwrócony Nodelist.
Jak widzisz tu jest native code.
Czyli nie wiemy, jaki kod jest pod spodem.
Bo to w ogóle nie jest kod JavaScript. Dom API zwraca nam listę wszystkich elementów, których szukaliśmy.
Ale nie wiemy jak to jest robione. Bo nie jest to robione w JavaScript. Ale poprzez JavaScript z tym możemy
się komunikować.
Czyli wiem, że jest to Nodelist.
Tak jak wspomniałem, my nie możemy napisać new Nodelist. Bo będzie to błąd, ale już wiem że jest to Nodelist.
No i teraz o co się w ogóle rozchodzi cała sprawa. O to, że wspomniałem, iż jest to obiekt tablicopodobny.
Na tablicy moglibyśmy wykonać forEach, a na takim obiekcie nie możemy.
Ja natomiast chciałbym, abyśmy mogli tutaj na tych elementach wykonać funkcje forEach i przekazać jej funkcję.
Ta funkcja tak jak w przypadku tablic będzie przyjmować element i każdemu elementowi przypisze kolor czerwony.
Chciałbym tak zrobić i gdyby była to tablica, mógłbym to zrobić.
Więc sprawdźmy i mamy błąd.
Elems.forEach is not a function. Czyli elems, tak jak wspominałem, jest to Nodelist.
Nie ma w swoim prototypie czegoś takiego jak forEach.
Możemy sobie tutaj to sprawdzić.
Nodelist.prototype i zaglądniemy do środka, czy coś tam jest, jak widzisz, item, length
czy get length.
Tutaj również mamy konstraktor.
Nie ma tam czegoś takiego. Jeżeli przejdziemy do kolejnego prototypu, to już jesteśmy w prototypie obiektu,
jak możesz zobaczyć, object i te rzeczy, które widzieliśmy.
Czyli jakby jest krótki tutaj ten łańcuch prototypowy, jak zazwyczaj bywa.
Nie ma takiej metody jak forEach.
Czyli moglibyśmy ją sobie tutaj dodać i teraz chciałbym to zrobić. Zanim te elementy sobie pobierzemy, odwołam
się do Nodelist.prototype i następnie metodę nazwę forEach.
Będzie to funkcja. Natomiast ta funkcja, widzisz tutaj forEach, musi przyjmować jako parametr inną funkcję,
którą wykonujemy. Więc nazwiemy ją callback, w ten sposób.
I tutaj wewnątrz będziemy chcieli przeiterować po wszystkich elementach. Czyli musimy zrobić pętle for.
Zrobiłem pętlę for i teraz może zastanawiasz się co to jest this.
Ale przypominam, że jeżeli dodajemy do prototypu Nodelist to this, to będzie konkretny element. Czyli
tutaj jeżeli to, jest to Nodelist, mówiłem ci, że jakby za naszymi plecami ktoś robi new Nodelist i nam to tutaj zwraca, to
w takiej funkcji jeżeli to dodamy do prototypu, tak samo jak wcześniej this będzie kierować na ten obiekt.
Czyli ten obiekt jest to obiekt tablicopodobny. No i moglibyśmy sobie na nim wykonywać pętle. Tak jak już to
wielokrotnie też w kursie podstawowym robiliśmy. Tutaj mógłbym napisać elems, a tutaj mógłbym wyświetlić
sobie console.log(elems[i]) i w ten sposób, i wszystkie elementy byśmy wywołali. Więc ja nic innego tam
nie robię. Tylko zamiast elemes napisałem this. Bo będziemy wewnątrz właśnie jakby takiego obiektu. Czyli tutaj
this tutaj będzie kierować na elemes. Jeżeli tu otworzymy inne zmienne właśnie z querySelectorAll, gdzie znowu będzie
Nodelist, no to this będzie kierować na kolejny element. No i teraz taką funkcję chcemy wywołać dla każdego
elementu i aby w tej funkcji parametr elem właśnie kierował na ten konkretny element. Konkretny element w
takiej pętli to będzie this[i], prawda? Jak to w pętli for. Czyli this[i] za każdym razem będzie konkretny element.
Czyli callback, też to bardzo dokładnie w pierwszej części kursu tłumaczyłem, który tutaj przekazujemy,
możemy taką funkcję przekazać sobie dalej, możemy ją też wywołać.
Ta całość będzie widoczna tutaj pod callback.
Czyli jeżeli sobie napiszemy callback, to mamy odwołanie do tej funkcji, a że ona przyjmuje jeden parametr, to ją możemy
z tym parametrem wywołać. Czyli z this[i]. W ten sposób wywołujemy tak naprawdę tę funkcję, która jest tutaj, jako
elem przekazując jej konkretny element.
No i teraz sprawdźmy. Teraz to zadziała. Jak widzisz przeiterowaliśmy przez wszystkie elementy i każdemu dodaliśmy
kolor czerwony. Gdybym sobie w tej funkcji to zmienił.
Załóżmy, że tego co mamy tutaj u góry nie widzisz w ogóle. To nam tutaj trochę miejsca i tak żebyśmy tego
nie widzieli, to nie istnieje. Rozszerzyliśmy prototyp i możemy teraz robić dowolne rzeczy. Mogę ten kolor
sobie zmienić na jakiś zupełnie inny.
Mogę tu napisać blue i to będzie działać.
Czyli dodaliśmy sobie pętle forEach do prototypu takiego właśnie Nodelist i teraz na koniec pytanie. Czy to
jest dobra praktyka, czy też nie?
Otóż nie powinniśmy rozszerzać wbudowanych prototypów. Bo teraz rozszerzyliśmy Nodelist. Jeżeli byśmy rozszerzyli
tablicę poprzez Array.prototype na przykład i ktoś by korzystał z naszej biblioteki, z naszego kodu to każdą
tablicę, którą sobie utworzy, nawet w ten sposób, jeżeli rozszerzony prototyp np. Array to ona będzie mieć
nowe metody.
Dlatego nie powinniśmy tego robić. Bo możemy zaskoczyć innych ludzi, że coś nie działa tak jak powinno.
Ktoś nauczył się JavaScript, od wielu lat z nim pracuje, chciał no sobie jakąś naszą bibliotekę, nie zagląda
tam bo ta biblioteka ma robić konkretne, rzeczy utworzył sobie tablicę, próbuje coś na niej wywołać i
coś działa inaczej niż on od zawsze wiedział, że powinno działać. Bo my mogliśmy coś nadpisać, mogliśmy
coś zmienić. Więc domyślnego zachowania JavaScript czy też obiektowego modelu dokumentu, jak widzisz, bo
możemy się do niego odwołać, w ten sposób, nie powinniśmy raczej zmieniać.
Natomiast dlaczego ci
to pokazuje. Po pierwsze jako ciekawostkę, a po drugie i ważniejsze dlatego, że często piszemy tzw. polyfille
albo z nich korzystamy. I są to biblioteki, które ktoś napisał. A więc np. mamy starsze przeglądarki,
które nie wspierają nowych metod tablic.
Ja pokazywały ci. że na tablicy możemy skorzystać właśnie z metody forEach.
W ten sposób. Jeżeli mieliśmy tablicę, to mogliśmy napisać forEach. To działa już od kilku lat we wszystkich
przeglądarkach nowoczesnych. Dlatego w pierwszej części kursu o tym mówiłem.
Natomiast kiedy wchodziły nowe przeglądarki, które wspierały forEach, a były na rynku jeszcze stare przeglądarki,
które tego nie wspierały to właśnie programiści pisali takie polifile, gdzie odwoływali się do Array.prototype.forEach,
a nie do Nodelist. Ale właśnie do Array. I pisali mniej więcej taką funkcję. Ja chciałem Ci to pokazać
akurat na Nodelist. I kiedy my sobie takie polifile na naszej stronie dołączaliśmy, to wówczas mogliśmy na tablicach
korzystać z forEach bez żadnego problemu.
Natomiast tutaj pokażę ci, że lepiej byłoby zrobić jeszcze if, w ten sposób. Czyli sprawdzamy czy typeof Nodelist.prototype.forEach
to nie jest funkcja.
Wiemy, że Nodelist.prototype nie zawierało forEach.
Czyli zwróci nam undefined, a więc nie będzie to funkcja.
Jeżeli to nie jest funkcja, czyli takiej funkcji tam nie ma. To tylko wtedy chcemy to dodać i tak działały polyfille.
Ale gdybyśmy tutaj to zmienili na Array. Tak to kiedyś działało.
Dzięki temu poniżej będziemy mogli na tablicy z tego korzystać.
A jeżeli kod się czyta w przeglądarce, która wspiera forEach, no to tutaj by zostało oczywiście zwrócone function
i ten kod by sie nie wykonał i byśmy tej metody niepotrzebnie nie nadpisywali.