od Podstaw
9 godz. 20 min · JavaScript · Full-stack i Programowanie
Piotr PalarzWeb DeveloperJavaScript to język programowania, który napędza niemal wszystkie strony internetowe. Dopełnia on technologie HTML i CSS, za pomocą których tworzymy strukturę i wygląd dokumentu. Co jednak w sytuacji, gdy chcemy po kliknięciu w wybrany przycisk wyświetlić powiększone zdjęcie lub wczytać dodatkowe dane z serwera? To właśnie w takich sytuacjach przydaje się język JavaScript i tzw. DOM API, dostępne w przeglądarce. Jak się przekonasz, możliwości nowoczesnych przeglądarek w połączeniu z tym językiem są naprawdę ogromne.
Język JavaScript może być używany nie tylko na stronach internetowych. Z tego powodu, w kursie omówimy najpierw najważniejsze konstrukcje tego języka, które są niezależne od platformy uruchomieniowej. Dzięki temu zbudujesz fundamenty niezbędne do tego, by wykorzystać ten język np. w środowisku Node.js. Krok po kroku omówimy sposoby tworzenia zmiennych, dostępne typy danych i operatory. Następnie zobaczysz jak tworzyć tablice i obiekty, z jakich instrukcji warunkowych i pętli możesz korzystać, a także jak tworzyć własne funkcje. Przekazywana wiedza uwzględniać będzie nowości, które pojawiły się w języku wraz z rewolucyjnym standardem EcmaScript 6 (ES6).
Sam język JavaScript to nie wszystko, by tchnąć ducha w strony internetowe. Z tego powodu, przeglądarki internetowe udostępniają tzw. DOM API. To interfejs, który z użyciem języka JavaScript pozwala na manipulację treścią i wyglądem strony. W kursie bardzo dokładnie omówimy czym jest Obiektowy Model Dokumentu, a także jak z nim pracować. Zobaczysz jak tworzyć nowe elementy HTML i wstawiać je na stronę, jak modyfikować ich treść, atrybuty, style czy klasy CSS. Poznasz sposoby na odczytywanie położenia elementu na stronie i jego wymiarów, które będą niezbędne w wielu sytuacjach. Dowiesz się także, jak przypisywać obsługę zdarzeń w przeglądarce, by np. wywołać własną funkcję, gdy ktoś kliknie w wybrany przez Ciebie przycisk.
JSON to popularny format wymiany danych, a Ajax to potoczna nazwa dla asynchronicznych zapytań HTTP, które wysyłać możemy z poziomu kodu JavaScript. Dziś niemal każda strona internetowa wykorzystuje te technologie. W niektórych przypadkach jako dopełnienie podstawowej funkcjonalności witryny, a w innych jako główny motor napędzający stronę. Jeśli kiedykolwiek widziałeś, jak na stronie internetowej jakaś treść "doczytuje" się np. podczas przewijania - widziałeś w praktyce Ajax. W jednym z rozdziałów kursu zobaczysz, jak pracować z tym formatem, a także jak wysyłać wspomniane zapytania do serwera.
Choć kurs który masz przed sobą, jest kursem dla początkujących, to aby zrozumieć jak działa język JavaScript i jak z nim się współcześnie pracuje, omówimy dwa ważne tematy - zarządzanie zależnościami i bundlowanie kodu. Dowiesz się czym jest npm i jak z jego pomocą pobierać paczki gotowego kodu z internetu, a także jak sprawić, by bez trudnu dołączać je do własnego kodu. W tym celu skorzystamy z narzędzia snowpack, które pozwoli nam także na optymalizację kodu przed jego wypuszczeniem w świat. Na tym etapie omówimy również jak działają moduły ESM, pozwalające dzielić kod na mniejsze części.
Kurs podzielony został na możliwie krótkie lekcje, do których w każdej chwili możesz wrócić. Jeśli zatem zapomnisz jak odczytywać wymiary elementu na stronie, szybko odnajdziesz odpowiednią lekcję. Czym jednak była by sama teoria i proste przykłady, bez pokazania, jak połączyć je w całość i wykorzystać w praktyce? Dobra wiadomość jest taka, że w kursie stworzymy aż 5 praktycznych projektów, wykorzystujących zdobytą wcześniej wiedzę. Najpierw napiszemy program losujący Dużego Lotka, następnie dynamiczny pasek postępu przeczytania artykułu, dymek pojawiający się nad elementem po najechaniu na niego myszą, wygenerujemy tabelkę w użytkownikami na podstawie danych JSON, a na koniec tworzymy prosty odtwarzacz wideo, z możliwością pauzowania i przewijania filmu.
Kurs ten jest dla wszystkich osób, które znają już podstawy HTML i CSS i chciałyby przejść poziom wyżej i dodać do swoich stron dynamiczności. Żadna wcześniejsza wiedza z zakresu JavaScript nie jest wymagana, ale zalecana jest podstawowa wiedza z zakresu samego programowania (czym są zmienne, pętle, funkcje itd.). Materiał ten będzie również świetnym odświeżeniem i usystematyzowaniem wiedzy dla osób, które już z tym językiem miały do czynienia. Po przerobieniu tego kursu będziesz gotowy, by poznawać język JavaScript dalej i zacząć korzystać z nowoczesnych frameworków.
W tej lekcji poruszymy bardzo ważny temat
dla języka JavaScript, mianowicie jak działa zakres zmiennych.
I teraz do tej pory my sobie tworzyliśmy w tym
pliku JavaScript jakieś zmienne czy jakieś funkcje i one były widoczne
tutaj w konsoli. Mieliśmy do nich odwołanie.
Generalnie nie jest to dobrą praktyką, ale nie chciałem tutaj niepotrzebnie śmiecić
w naszym kodzie, żeby dodawać jakieś dodatkowe funkcje.
Niemniej jednak jak będziemy pracować w trochę nowocześniejszy sposób z językiem
JavaScript, czyli z użyciem tak zwanych bundlerów kodu, o których jeszcze Ci powiem
w tym kursie, to one tak czy siak te nasze wszystkie zmienne będą opakowywać w taki
sposób funkcje, że nie będzie to przeciekać do tego globalnego zakresu.
Dlaczego nie jest dobrze, jeżeli np.
utworzymy sobie jakąś zmienną, powiedzmy firstName
Piotr,
że ona jest widoczna tutaj, no z tego powodu,
że z dowolnego innego kodu ktoś będzie mógł się do niej odwołać albo ją
zmodyfikować, gdyby była utworzona z let.
A na stronie czasami jest tak, że mamy sporo tych różnych skryptów podpiętych i
ktoś w swoim skrypcie mógł tak samo nazwać jakąś zmienną jak my
itd.
Więc generalnie dobrze, żeby zakres zmiennych ograniczać.
I w języku JavaScript są w zasadzie dwa sposoby na ograniczenie zakresu zmiennych.
Pierwszym z nich jest funkcja.
Czyli gdybyśmy sobie utworzyli tutaj funkcję init, to ta funkcja będzie globalna.
Ona będzie wszędzie dostępna, ale wszystko
co utworzę wewnątrz już nie będzie dostępne na zewnątrz.
Więc jak sobie tutaj utworzę firstName
równa się Piotr i mam sobie taką oto funkcję, to nigdzie tutaj do tego firstName
nie mogę się odwołać. Jedynie do funkcji init. Ale nawet jak ją wywołam to nadal do
tego firstName nie mam dostępu, bo taki blok kodu funkcji tworzy nam nowy zakres zmiennych.
Czyli można powiedzieć, że tu jest jeden
zakres, a ponad nim jest ten globalny zakres. I tych zakresów może być więcej, bo
jeżeli wewnątrz jednej funkcji utworzę inną np.
sayHello, jak najbardziej możemy to zrobić
i tutaj sobie powiem lastName równa się Kowalski
to teraz wewnątrz tego zakresu, tej wyższej funkcji nie mam dostępu do lastName.
Ale wewnątrz funkcji sayHello mam dostęp i do lastName i do firstName.
Dlatego, że w każdej z tych funkcji mamy dostęp do wszystkich zmiennych i także
funkcji, które są utworzone we wszystkich wyższych zakresach. Czyli w tym zakresie
jak jest firstName to w tej funkcji też to będzie dostępne oraz wszystko inne, co
jest globalne, takie jak na przykład window.
No i teraz zauważ możemy z tej funkcji sobie zrobić console.log,
np. taką interpolację tutaj sobie zrobimy
i będzie tam firstName z tego górnego zakresu i lastName z naszego zakresu.
Tylko teraz tę funkcję trzeba wywołać, więc wywołajmy ją tutaj
sayHello to jeszcze nic nie da, bo jej wywołanie jest w funkcji init, więc musimy
jeszcze wywołać funkcję init jak initialize.
I zobacz teraz jak najbardziej nam to będzie działać.
Mamy Piotr Kowalski.
Kolejnym tematem, o którym powiem jest przesłanianie zmiennych.
Działa to w ten sposób, że skoro tutaj
odwołaliśmy się do firstName i w zakresie tej funkcji nie ma firstName, to zostało
to wyszukane w innym zakresie, ale mógłbym sobie tutaj powiedzieć const fastName
równa się Maciej i wtedy nie ma żadnego błędu.
Jak się odwołujemy do firstName to weźmiemy to z tego zakresu.
Zobacz, teraz zobaczymy tutaj Maciej Kowalski i nie ma żadnego błędu.
Natomiast gdybym tutaj chciał jeszcze raz zrobić firstName, na przykład Maciej
to otrzymamy błąd, że próbujemy nadpisać stałą, która już istnieje. A w innym
zakresie jak widzisz tego problemu już nie ma.
Skoro funkcja init ograniczyła nam wszystko co jest wewnątrz do tego zakresu,
to znaczy, że tutaj na zewnątrz też nie możemy się odwołać do funkcji sayHello.
Gdybyś chciał sprawić, że jakaś funkcja
jest globalna, to możesz ją przypisać do globalnego obiektu jakim jest window np.
window.sayHello równa się sayHello.
Albo mógłbyś tutaj podać inną nazwę np.
window.hello równa się sayHello,
wtedy będziemy mogli globalnie się odwołać do hello
i to jest dokładnie to samo,
albo do window hello, też to będzie to
samo. Ale zazwyczaj robimy tak, że sobie to w ten sam sposób nazywamy.
Ale zauważ jedną ciekawą rzecz. Odwołaliśmy się do tej funkcji sayHello z poziomu
globalnego, bo jest teraz przypisana do obiektu window i ona cały czas ma dostęp
do Maciej Kowalski czyli do tych wszystkich wartości w miejscu, w którym
została zdefiniowana. A mimo tego, że odwołujemy się do niej tutaj, można
powiedzieć na zewnątrz. Więc również o tym
warto wiedzieć, że funkcje, nieważne gdzie są wywołane, one widzą i pamiętają zakres
zmiennych z miejsca, w którym zostały zdefiniowane.
Wspomniałem, że mamy dwa sposoby na ograniczenie zakresu.
Pierwszy jest to stworzenie nowej funkcji, a drugi jest to stworzenie bloku.
Czyli na przykład jak mamy instrukcję warunkową if i tutaj zrobię true tylko po to,
żeby ona się zawsze wykonała, to jak w niej sobie utworzę jakąś zmienną np.
number równa się 10, to w całym tym bloku kodu tutaj pomiędzy
tymi nawiasami mam do niej dostęp, ale jakbym chciał zrobić console.log number
poza takim blokiem to otrzymamy błąd number is not defined.
Czyli taki blok również ograniczył nam zakres zmiennych, ale tylko wtedy kiedy są
one tworzone w ten nowszy sposób, czyli z użyciem let lub const.
A gdybyś wykorzystał stary JavaScript zapis taki jak var, to wtedy już nie
będzie to ograniczone i dostęp do tego 10 uzyskamy. Z tego również powodu
nie jest dobrą praktyką korzystanie dzisiaj ze słowa kluczowego var.
Na sam koniec pokażę Ci jeszcze jeden sposób.
Jeżeli nie chcesz tworzyć nazwanej funkcji init i później ją wywoływać, to jest jeden
ciekawy sposób jak sobie w pliku JavaScript stworzyć nowy zakres zmiennych właśnie po
to, żeby wszystko co tworzymy nie przeciekało
tutaj do tego globalnego zakresu, a co za tym idzie nie było też dostępne w innych
skryptach, gdyby ktoś tutaj miał jakiś inny skrypt,
nie chcemy, żeby ten skrypt miał dostęp do
naszych zmiennych, to możemy zamiast takich funkcji init utworzyć funkcję anonimową
a tą funkcję init może ja po prostu wykomentuje, ale najpierw sobie skopiuję
wszystko co było wewnątrz, teraz ją wykomentuje.
Zobacz, utworzyłem funkcję anonimową i wszystko do niej wstawiłem.
Czyli ona nie ma żadnej nazwy,
a więc ta nazwa taka jak init nie będzie się pojawiać w globalnym zakresie.
Ale teraz jak tę funkcję wywołać?
Okazuje się, że wystarczy ją opleść w takie nawiasy.
Wtedy będzie to traktowane jak takie wyrażenie.
I skoro to nam zwraca taką funkcję, to możemy ją takimi nawiasami wywołać.
I to nazywa się self in working anonymous
function, czyli samo wywołująca się funkcja anonimowa.
W ten sposób jest ona tworzona i od razu jest wywoływana.
Dzięki temu cały nasz kod się wykona, ale
żadne z tych zmiennych nie przeciętną do globalnego zakresu.
Oczywiście oprócz tych, które celowo np.
do obiektu window przypisaliśmy.
No i dodatkowo skoro ta funkcja nie ma
nazwy, to nie zaśmiecamy globalnego zakresu żadną nazwą.
Zauważ, że efekt będzie teraz dokładnie
taki sam, włącznie z tym błędem, który znajduje się tutaj.
To zatem tyle, jeśli chodzi o zakres zmiennych.
Pamiętaj, że każda funkcja ma swój własny zakres zmiennych, ale jeżeli tam się
odwołamy do czegoś, co nie istnieje w tym zakresie, jest to wyszukiwane w wyższym
zakresie i wyższym aż do globalnego zakresu na obiekcie window.