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 chcę Ci pokazać bardzo ważny operator "in" oraz metodę "hasOwnProperty", która jest dziedziczona
dla wszystkich obiektów z object.prototype. I przejdźmy od razu do rzeczy.
Mam tutaj utworzony prosty obiekt i teraz gdybyś chciał sprawdzić, czy w takim obiekcie istnieje jakaś
właściwość, to mógłbyś napisać if(person.lastName).
Jeżeli jest taka właściwość, to chcemy coś zrobić np. to wyświetlić czyli person.lastName.
No i zobaczmy, w konsoli wyświetlamy Kowalski.
Natomiast jeżeli dobrze rozumiesz JavaScript to wiesz, że tutaj pojawił się problem. Bo jeżeli person.lastName będzie
miało wartość pustą,
pusty ciąg znaków. Albo może inaczej. Zróbmy tutaj age.
Jeżeli person age jest 34, w porządku. Zostało zwrócone. Ale jeżeli age bym ustawił na zero, to nam się
ten kod nie wykona. Dlatego, że zero będzie uznawane za wartość fałszywą. Więc nie zawsze dobrze jest sprawdzać
to w ten sposób. Jeżeli chcesz sprawdzić, czy w jakimś obiekcie jakaś właściwość w ogóle istnieje.
Jeszcze jest jeden problem. Gdybyśmy jakieś właściwości przypisali tak jak tutaj np. 0, to jak widzisz, jest
to wartość fałszywa i w ogóle to się nie wykonało.
Ale jeżeli w ogóle tam nie będzie istnieć taka właściwość czyli np. age, w ten sposób, to również jakby jest
to adekwatne.
Z tego powodu, że jeżeli odwołamy się do person.age, zobacz. Age, 2 razy. Takie, które nie istnieje, zostaje
zwrócone undefined. Jest to wartość fałszywa. Więc if się nie wykonuje.
Natomiast co prawda moglibyśmy do pewnych składowych przypisać wartość undefined. Ale zazwyczaj tego
nie robimy. Częściej jest to null. Niemniej jednak nie ma jakby to większego znaczenia.
Jak widzisz problemy mogą się pojawić. Dlatego teraz chcę ci pokazać operator in, który takie problemy pozwala
rozwiązać.
Podobnie jak w pętli for in, którą się jeszcze za moment zajmiemy,
możemy korzystać z operatora in, który po lewej swojej stronie przyjmuje String. Czyli jeżeli chcemy sprawdzić
czy age, czy taka właściwość w ogóle się znajduje w person, musimy napisać to w ten sposób. Czyli String
i w "age" in person.
W ten oto sposób. To wtedy chcemy go wyświetlić.
I mimo tego, że tutaj jest zero, zobacz. Wyświetliliśmy sobie to zero. Czyli zostało nam zwrócone true.
Jeżeli tutaj byśmy sprawdzili "age" in person, bo ważne jest, że ten operator, tu oczywiście musi być obiekt.
Bo to działa na obiektach wyłącznie. Jeżeli mamy "age" in person to zostanie zwrócone true.
Ten operator in zawsze zwraca true lub false, nic innego.
Mamy true, "age" in person.
W ten oto sposób. Natomiast jeżeli nie mamy tutaj age z dwoma "e", możemy to sprawdzić. To możemy tak napisać.
False. Jak widzisz, działa nam to teraz dobrze. Czyli jeżeli chcesz sprawdzić czy jakaś właściwość jest
w jakimś obiekcie, możesz to zrobić w ten sposób. W poprzedniej lekcji pokazywałem ci rozszerzenie prototypów
i tam mówiłem, że możemy sprawdzić na przykład czy w NodeList mamy taką metodę jak forEach. Robiliśmy
to w ten sposób. Być może pamiętasz. Jeżeli typeof Nodelist.prototype.forEach nie jest równe funkcji. Ale możemy
to zrobić też podobnie. Napisać tutaj po prostu if ("forEach",
tutaj wielkość liter ma znaczenie,
in Nodelist.prototype) .
Bo to jest obiekt.
To znowu będziemy mieli true lub false.
Czy tam taka właściwość się znajduje.
Więc to należy zapamiętać.
Teraz kolejna rzecz, którą chce ci pokazać jest to metoda hasOwnProperty.
Bo teraz będę chciał przeiterować sobie po całym tym obiekcie pętlą for in czyli tworzymy tutaj zmienną
i in person.
Dzięki takiemu zapisowi, już to też tłumaczyłem w pierwszym kursie, możemy pod i mieć te klucze, które tutaj się
znajdują. W zasadzie nazwijmy to key.
No i jeżeli zrobimy consol.log(key), to proszę bardzo, nie ma problemu. Wyświetlamy firstName, lastName i age. Czyli tylko
te, które tutaj się znajdują.
Wydawałoby się, że nie ma żadnego problemu.
No to teraz chciałbym tutaj stworzyć sobie pewien obiekt, w sposób taki jak już się uczyliśmy. Czyli jako
konstruktor. Wkleję tutaj Person, firstName, lastName i age.
Czyli będzie to podobne do tego. I teraz sobie go będziemy chcieli pod spodem utworzyć. Może w tym miejscu.
Ok i teraz będziemy po person2 chcieli iterować.
Zobaczymy czy coś się zmieni.
Nic się nie zmieniło.
Dokładnie działa to w ten sam sposób. Bo person2 przekazaliśmy tutaj, jak wiesz, będzie mieć firstName, lastName i
age.
Natomiast zauważ, co stanie się teraz. Jeżeli będę chciał do person.prototype dodać sayHello.
Domyślasz się, że dzięki sayHello będziemy mogli wywoływać person2.sayHello.
Ale co możesz już tutaj zobaczyć, sayHello się tutaj pojawiło.
Czyli chwila. Iterujemy sobie teraz tutaj po wszystkich właściwościach obiektu person2.
Tam powinno być w firstName, lastName oraz age, a jeszcze sayHello się pokazało. Dlaczego tak jest?
Otóż z tego powodu, że pętla, w której korzystamy z operatora in
sprawdza, czy gdziekolwiek w prototypie znajduje się jakiś klucz.
Podobnie byłoby tutaj wyżej. Kiedy napisałem ci if, coś tam in coś tam, jakiś obiekt to zostanie nam zwrócone
true lub false. Niezależnie czy bezpośrednio na obiekcie to zostanie znalezione, czy gdzieś na jego prototypie.
Teraz jak można sobie z tym poradzić i dlaczego jakby nie występuje ten problem przy innych obiektach.
Dlaczego jeżeli iterujemy tutaj po person2 to sayHello się pokazało. Ale nie pokazuje się masa innych rzeczy,
które są przypisane np. do object.prototype. Wiesz,
że tam jest dużo funkcji. Z tego powodu, że wbudowane w JavaScript funkcje są oznaczone jako nonenumerable.
Czyli nie są jakby wyliczalne, nie można ich w pętli for in wyliczyć. I my możemy oznaczać, tworząc taką
właściwość jak tutaj, jak sayHello,
jako nonanumerable. Moglibyśmy to tak oznaczać, żeby właśnie on, to tutaj się nie wyświetlało.
Natomiast są to koncepcje jeszcze troszkę bardziej zaawansowane. Ja ich w tym kursie nie poruszam. Planuję
zrobić osobny warsztat na ten temat. Pod koniec tego kursu jeszcze będę o tym wspominał. Więc będziesz mógł również
się tego dowiedzieć.
Czyli wbudowane w JavaScript metody czy właściwości są często oznaczone jako nonanumerable, a te które my dodamy
do prototypu są anumerable. Czyli wyliczane. I teraz jak sobie z tym poradzić.
Otóż każdy obiekt ma taką metodę jak hasOwnProperty, która jest dziedziczona z object.prototype. Więc
możemy to w ten sposób sprawdzić.
Skoro person2, tutaj, jest to obiekt, dziedziczy również z object.prototype.
Najpierw ze swojego prototypu potem z object.prototype, to ma dostęp do metody hasOwnProperty.
I tutaj możemy przekazać właśnie taką nazwę czyli np. moglibyśmy tutaj napisać firstName, prawda?
I tutaj zostanie zwrócone true lub false.
Czy taki obiekt person2 ma własną właściwość "firstName".
On ma własną. Bo jest bezpośrednio do niego przypisana, a jeżeli jest na prototypie, to już nie jest własna.
Czyli tutaj kiedy sobie to wszystko wyliczamy,
zauważ, że key na końcu ma sayHello. To jest String. Więc to key możemy tutaj przekazywać. I teraz z tej pętli za każdym
razem będzie sprawdzane czy person2.hasOwnProperty.
firstName to prawda, lastName też, age też. Bo one są na nim przypisane.
Ale kiedy dojdziemy do sayHello, tutaj zostanie zwrócone false.
I dlatego możemy to zapisać w if, w ten oto sposób. I tylko wtedy, jeżeli dany obiekt ma własną właściwość,
to będziemy chcieli ją wyświetlić.
W ten oto sposób. Zobaczymy. I teraz tylko w firstName, lastName oraz age zostały wyświetlone.
Podobnie, jak wspominałem, będzie zawsze z operatorem.
in.
Jeżeli zapytamy tutaj person2, tutaj zapytamy sayHello in person2. Jak widzisz mamy true. Chociaż zostało
to znalezione na prototypie person2.