od Podstaw
10 godz. 55 min · JavaScript · Full-stack i Programowanie
Piotr PalarzWeb DeveloperJeśli poznałeś już wymienione wyżej technologie, to zapewne zdajesz sobie sprawę z ich ograniczeń. Za pomocą języka HTML tworzymy bowiem strukturę dokumentu, dodajemy treść tekstową, obrazy czy wideo. Aby jednak strona internetowa wyglądała perfekcyjnie, korzystamy z arkuszy stylów CSS, które pozwalają nam opisać wygląd wszystkich elementów HTML, ustawić wielkość tekstu czy dodać tło strony. No właśnie, ale gdzie tutaj interakcyjność?Zapewne już wiesz, że język CSS oferuje tzw. pseudoklasy, które pozwalają nam np. przypisać zmianę koloru elementu po najechaniu na niego kursorem myszy. I to tak naprawdę wszystko, na co możemy zareagować. A co gdybyśmy chcieli po wciśnięciu jakiegoś przycisku wysunąć ukryty panel, sprawdzić poprawność wypełnianego właśnie formularza lub pobrać dane z serwera i wyświetlić je na stronie bez przeładowywania witryny? Dobra wiadomość jest taka, że to wszystko jest możliwe z użyciem języka JavaScript, który “rozumie” każda przeglądarka internetowa.Choć język JavaScript powstał jako język skryptowy na potrzeby stron internetowych, to już dawno temu “wyszedł” z przeglądarek internetowych i może być używany tak naprawdę gdziekolwiek. W kursie, który masz przed sobą, poznasz język JavaScript jako niezależny język programowania, a dopiero później dowiesz się, jak wykorzystywać go do wzbogacania stron internetowych. Dzięki postawieniu grubej linii pomiędzy samym językiem, a Obiektowym Modelem Dokumentu dostępnym w przeglądarkach internetowych, będziesz nie tylko bardzo dobrze rozumiał sam język, ale w przyszłości wykorzystasz go do innych zastosowań.Na początku omówimy ciekawą historię języka JavaScript, a chwilę później rozpoczniemy poznawanie najważniejszych jego konstrukcji. I tak dowiesz się czym są zmienne, jakie typy danych dostępne są w tym języku, czym są liczne operatory, instrukcje warunkowe, pętle, tablice, obiekty i funkcje. Wszystkie te zagadnienia są bardzo podobne w innych językach programowania, dlatego kurs ten jest również świetnym wstępem do programowania w ogóle. Każda z przedstawianych konstrukcji języka jest bardzo dokładnie tłumaczona z myślą osobach początkujących. Nie zmienia to jednak faktu, że nawet osoby znające już podstawy języka JavaScript znajdą tutaj coś dla siebie, gdyż na każdym etapie przedstawiane są również liczne ciekawostki odnośnie danej konstrukcji.Kiedy zrozumiesz już jak działa język JavaScript, przejdziemy do drugiej połowy kursu, gdzie dokładnie omówimy Obiektowy Model Dokumentu, dostępny w przeglądarkach internetowych. Zobaczysz jak przeglądarka tworzy z kodu HTML drzewo dokumentu, jak reprezentowane są poszczególne jego węzły, a także jak język JavaScript potrafi z tym “wewnętrznym światem” współpracować. Dowiesz się jak wyszukiwać na stronie interesujących nas elementów HTML, a także jak tworzyć nowe elementy, przypisywać im treść i wstawiać je na stronę. Popracujemy również z atrybutami elementów, ich klasami i wreszcie ze stylami CSS, abyśmy mogli wpływać dynamicznie na wygląd naszej strony.Zobaczysz również, jak możemy w dowolnym momencie odczytać współrzędne położenia elementu na stronie, a także jego wysokość czy szerokość. Tę wiedzę wykorzystamy później w praktycznym przykładzie.Jeden z rozdziałów kursu poświęcony został zdarzeniom, a więc możliwości reagowania na zachowania użytkownika. Dzięki temu zobaczysz, jak możemy przypisać np. zdarzenie kliknięcia do wybranego elementu, a kiedy zostanie on kliknięty, wykona się przygotowany przez nas kod. Poznasz kilka różnych sposobów na przypisywanie oraz usuwanie zdarzeń, a także dowiesz się czym jest tzw. “bubbling” oraz “capturing” czy jak zablokować domyślną akcję przeglądarki.Przy pisaniu jakiegokolwiek kodu, zawsze pojawiają się błędy, dlatego i tutaj Twoje wątpliwości nie pozostaną bez odpowiedzi. Poznasz wszystkie typu błędów, które mogą się pojawić podczas wykonywania naszego kodu, a także wiele sposobów ich wykrycia i wyeliminowania.W kursie nie brakuje oczywiście praktycznych przykładów, które celowo zostały ułożone tak, aby wykorzystać w nich jak najwięcej zdobytej wcześniej wiedzy. Nie zostaniesz więc sam z poczuciem, że co prawda rozumiesz jak działa dana konstrukcja, ale nie masz pomysłu, kiedy z niej skorzystać. Na początek wykonamy praktyczny projekt losowania liczb z wybranego przedziału tak, aby nie mogły się powtórzyć. Już przy tym projekcie poznasz wiele ciekawych technik i sztuczek.Następnie przejdziemy do nieco bardziej zaawansowanego przykładu i napiszemy skrypt, który pozwoli nam sortować dane w tabeli po wybranych kolumnach, kiedy któraś z nich zostanie kliknięta. Zobaczysz jak sortować dane zarówno malejąco jak i rosnąco, a także jak zmieniać kolejność elementów HTML na stronie.W kolejnym projekcie zajmiemy się walidacją danych wpisywanych do formularza, by ten nie mógł zostać wysłany do serwera tak długo, jak zawiera jakiekolwiek błędy. Zobaczysz tutaj zdarzenia związane z polami formularza, a także sposoby na pobieranie z nich wartości i sprawdzanie czy są one poprawne. Zadbamy także o wrażenia użytkownika i wyświetlimy na stronie stosowne błędy, a także podświetlimy źle uzupełnione pola na czerwono.W przedostatnim projekcie wstawimy na stronę przycisk, który będzie się pojawiał po przewinięciu strony w dół, a znikał po odwrotnej akcji. Co jednak ciekawe, po jego kliknięciu, strona zostanie automatycznie, płynnie przewinięta do samej góry.W ostatnim projekcie stworzymy bardzo efektowny dymek z podpowiedzią, który będzie się pojawiał nad elementem po najechaniu na niego kursorem myszy. Wykorzystamy tutaj mnóstwo ciekawych technik. Dowiesz się również jak swój kod przygotować w taki sposób, abyś mógł go udostępnić innym osobom, by w łatwy sposób skorzystały z przygotowanego Tooltipa na swoich stronach.Kurs kończy się sekcją Tips & Tricks, w której znajdziesz 10 krótkich lekcji. W każdej z nich została omówiona jedna sztuczka. Każda z nich pozwoli Ci jeszcze lepiej zrozumieć język JavaScript, ale przede wszystkim zaoszczędzić czas i kilka linijek często niepotrzebnego kodu.Podsumowując, kurs ten jest nie tylko wprowadzeniem do samego języka JavaScript, ale także do Obiektowego Modelu Dokumentu. Dzięki wyraźnemu rozdzieleniu tych dwóch zagadnień, będziesz mógł w przyszłości wykorzystać język JavaScript także do innych zastosowań, poza przeglądarką internetową.
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 czy programowania nie jest wymagana, gdyż wszystkie konstrukcje są starannie tłumaczone. 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, z kursem JavaScript w Praktyce, który powstał jako dopełnienie tego kursu i porusza nieco bardziej zaawansowane tematy, na które tutaj zabrakło już czasu.
W tej lekcji kontynuujemy poznawanie funkcji i porozmawiamy o rzeczy bardzo istotnej.
Ja postanowiłem zostawić to właśnie na ten czas, kiedy już poznasz większość konstrukcji języka JavaScript
i kiedy będziemy mówić o funkcjach, chcę porozmawiać o zakresie zmiennych, a więc gdzie nasze zmienne
są widoczne, bo być może już się nad tym zastanawiałeś.
Przejdźmy do kodu.
Przechodzimy do scripts.js i będę chciał utworzyć funkcję znaną nam już, sayHello.
Powiedzmy, że ta funkcja będzie robić console.log, tak jak wcześniej.
I tutaj będę chciał dodać firstName.
Natomiast firstName nie będzie przekazywane tutaj,
ale utworzymy tam zmienną.
Gdzieś wyżej i teraz i jak się możesz już domyślić, taka funkcja mam bez problemu zadziała.
Mamy utworzoną zmienną, mamy tutaj funkcję i ta funkcja będzie miała dostęp do właśnie tej zmiennej, bo
są one w jednym zakresie zmiennych.
Przejdźmy sobie tutaj odświeżmy i teraz wpisze sobie sayHello.
No i zobaczmy,
Cześć Maciej.
Faktycznie, tutaj się wyświetla.
Natomiast, do tej pory pokazywałem, że w konsoli przeglądarki bez trudu możemy się odwołać do tych wszystkich
zmiennych.
No i teraz pytanie, czy tak być powinno, czy też nie.
Otóż w większości przypadków, tak być nie powinno.
I teraz pokażę ci dlaczego. Mamy tutaj plik scripts.js,
który został podlinkowany w pliku index.HTML.html,
w tym miejscu. Natomiast co by było, gdybyśmy podlinkowali sobie tutaj kolejny plik.
No bo tak zazwyczaj robimy, tworząc aplikacje internetowe czy korzystając z innych skryptów jak np. biblioteka
jQuery, którą tutaj byśmy linkowali.
Powiedzmy, że mamy plik, który nazywa się scripts2.
Ja go teraz utworzę w katalogu js, scripts2.js i sprawdźmy czy będziemy mogli wpisać console.log,
firstName.
Widzisz, że w tym pliku nigdzie nie zdefiniowaliśmy takiej zmiennej, ale zdefiniowaliśmy ją w tym miejscu,
a ten plik scripts2 następuje po tym pliku.
Czyli przeglądarka wczytując tą stronę pobierze sobie ten plik w całości go wykona i dopiero później
wykona kolejny.
A więc w pamięci powinna mieć już taką zmienną jak firstName.
Teraz odświeżmy sobie tutaj. Jak widzisz Maciej się wyświetliło.
I tutaj mamy pokazane, że zostało to zrobione w pliku scripts2.
Właśnie poprzez ten console.log, no i teraz czy jest to rozwiązanie dobre?
Pewnie domyślasz się, że nie, bo jeżeli ty napiszesz jakiś kod, który powiedzmy komuś udostępniasz i nazywasz
swoje zmienne tak jak tobie to pasuje np. firstName itd.
To co, jeżeli ktoś sobie taki kod podlinkuje i następnie wpisze sobie jakieś swoje skrypty albo inaczej
mówiąc, jeżeli ty podlinkujesz sobie kod, który ktoś wcześniej napisał, a później swoim pliku będziesz chciał
skorzystać zmiennych o takich samych nazwach, to będziesz miał problem
i błąd bo będziesz chciał zadeklarować zmienne, które już wcześniej w pamięci istnieją. Z tego powodu istnieje
coś takiego jak zakres zmiennych, które chciałbym teraz omówić. Stworzymy sobie wewnątrz funkcji, co jest bardzo
istotne zmienną, którą nazwiemy lastName i napiszę tutaj Kowalski.
No i tutaj standardowo będę chciał wyświetlić firstName plus spacja plus lastName.
Przejdźmy sobie tutaj. Odświeżam.
No i teraz wpiszemy sayHello.
Cześć Maciej Kowalski.
Wszystko działa poprawnie. Natomiast wiesz, że możemy tutaj odwołać się do firstName, Maciej.
Spróbujmy odwołać się do lastName.
No i okazuje się, że nie mamy dostępu w ogóle do takiej zmiennej,
lastName is not defined. Zdefiniowaliśmy to wewnątrz funkcji,
a poza tą funkcją, czyli tutaj w przeglądarce, nie jest dostępne w dokładnie w taki sam sposób jak nie byłoby
dostępne tutaj, czyli jeżeli tutaj wpisze lastName, sprawdźmy. Znowu mamy ten sam błąd. Nie możemy odwołać
się do takiej zmiennej.
Oznacza to tylko tyle i jest to bardzo ważne i chciałbym, żebyś to zapamiętał, że funkcja ogranicza nam
zakres zmiennych albo inaczej tworzy nowy zakres zmiennych.
Jeżeli tutaj wpiszemy lastName, to tylko wewnątrz tej funkcji będzie dostęp do takiej zmiennej.
Gdybym chciał na zewnątrz mieć taki dostęp, to musiałbym tutaj wpisać return lastName.
Ale zdajesz sobie sprawę, że nadal będziemy mieli błąd, bo nie zwracamy jakby zmiennej, ale wartość którą
ona reprezentuje, czyli tam gdzie wywołamy sayHello zostanie zwrócone Kowalski, czyli tak naprawdę nie
mamy nigdzie dostępu do takiej zmiennej.
I teraz, co jest dobre, to fakt, że możemy bez problemu w swoich funkcjach tworzyć sobie dowolne nazwy zmiennych.
A poza funkcjami możemy tworzyć takie same nazwy zmiennych,
jeżeli w tym pliku ktoś by stworzył sobie albo w tym poprzednim jakieś podobne nazwy zmiennych, które
byłyby pokrywające się z tymi które my tworzymy.
Nie będzie konfliktu, jeżeli to będzie wewnątrz funkcji.
Chciałbym tutaj jeszcze wspomnieć, o zakresie zmiennych w różnych blokach kodu np. w instrukcjach warunkowych.
Dlatego, że w pewnych językach programowania, jeżeli mamy blok np. if, tutaj będzie true, to to co zawrzemy
tutaj to jest właśnie oznaczenie bloku kodu.
To tutaj możemy tworzyć nowe zmienne.
Czyli gdybym tutaj napisał np. age równa się 32, to ta zmienna nie byłaby dostępna w innych
miejscach. W JavaScript'cie
natomiast, jeżeli ten warunek tutaj będzie prawdziwy i ten kod się wykona, to ta zmienna będzie oczywiście
widoczna tutaj gdzieś poniżej. Ona zostałaby ograniczona gdyby oczywiście była stworzona wewnątrz funkcji,
w ten sposób. Natomiast sam blok nie tworzy nowego scope, czyli zakresu zmiennych.
Podobnie będzie w przypadku pętli for itd.
Więc jedyna konstrukcja, która ogranicza zakres zmiennych w języku JavaScript,
jest to funkcja i gdybyśmy chcieli, aby te globalne tutaj zmienne nie były widoczne np. w przeglądarce
czy w innych skryptach, to to wszystko musimy objąć funkcją
i powiedzmy, że nazwiemy tę funkcję init.
w ten sposób i wszystko, co tutaj mieliśmy,
wrzucimy do tej właśnie funkcji,
w ten sposób. To możemy usunąć.
Jedyne, co pozostało nam zrobić, to wywołać taką funkcję
init
i teraz wszystko, co sobie tutaj zawrzemy,
bez trudu,
będzie dla nas działać, ale nie będzie widoczne na zewnątrz.
Oczywiście teraz nie moglibyśmy skorzystać z sayHello. Tutaj w przeglądarce. Gdybym sobie wpisał sayHello,
w ten sposób, bo nie jest to dla nas dostępne.
Ale tutaj w kodzie możemy z tego korzystać.
I zazwyczaj właśnie będziemy nasze aplikacje oplatać taką dodatkową funkcją. Może to być również funkcja
anonimowa, o czym powiemy jeszcze w jednej z kolejnych lekcji.
Ostatnią istotną rzeczą jest fakt, że kiedy przekazujemy do funkcji jakieś parametry, to one również są
dostępne jako lokalne zmienne, ale myślę, że to już rozumiesz. Gdyśmy tutaj wpisali tekst, to możemy tutaj się odwoływać do
tej zmiennej jako text, czyli tak jak byśmy utworzyli sobie taką zmienną tekst poprzez var text wewnątrz.
i jakby ona miała wartość, która została do funkcji sayHello przekazana. Tyle wystarczy, że zapamiętasz,
a więc zmienne są zawsze widoczne tylko wewnątrz takiej funkcji.
I teraz jeszcze jedna sprawa.
Mianowicie chciałem abyś wiedział, że w JavaScript'cie istnieje coś takiego jak Garbage Collector.
Inaczej mówiąc odśmieciarz.
Jest to mechanizm, który sam usuwa z pamięci niepotrzebne już dane. W niektórych językach programowania
niskiego poziomu sami musimy zadbać o to, aby kiedy utworzymy taką zmienną jak np. firstName w momencie
kiedy nie jest nam ono już potrzebne, aby zwolnić pamięć i taki string usunąć z pamięci operacyjnej komputera.
W JavaScript'cie nie musimy tego robić, bo jest to za nas zrobione poprzez tzw. Garbage Collector i to jest
mechanizm, który wie kiedy może pewne zmienne usuwać.
Zauważ, że tutaj wewnątrz funkcji stworzyliśmy nową zmienną lastName.
Jest to Kowalski i taki Garbage Collector wie, że kiedy wykonujemy taką funkcję to lastName jest nam potrzebne,
ale tylko do końca tej funkcji, bo sam już wiesz, że poza tą funkcją lastName nie jest dostępne,
czyli kiedy taka funkcja się wywoła,
odśmieciarz sam usunie z pamięci ten string Kowalski i nie musimy się tym martwić.
Na sam koniec tej lekcji, chciałbym ci powiedzieć jeszcze o jednej niesłychanie ważnej rzeczy w języku
JavaScript, w kontekście zakresu zmiennych.
Mianowicie o fakcie, że funkcja ma dostęp do zmiennych tam, gdzie została zdefiniowana, a nie tam gdzie
jest uruchamiana.
Mamy tutaj funkcję sayHello i wspomniałem ci, że w pliku scripts2 nie będziemy do niej mieli dostępu.
Z tego powodu, że ona jest wewnątrz funkcji init.
Natomiast jeżeli tutaj, wcześniej, tę funkcję przypiszemy do obiektu globalnego Window, o którym jeszcze w
tym kursie będę mówił.
Mamy taki obiekt globalny jak Window i napiszemy sobie tutaj czy to sayHello czy dowolną inną nazwę możemy tutaj
przyjąć.
Możemy napisać nawet hello, to nie ma znaczenia i przypiszemy sayHello, to mówimy, że chcemy w obiekcie Window
utworzyć sobie taką właściwość, która będzie kierowała na tę właśnie funkcję, która znajduje się tutaj.
Oznacza to tylko tyle, że będziemy teraz mogli przejść do scripts2 tutaj i będziemy sobie mogli uruchomić
funkcję, która znajduje się pod Window Hello.
A jeżeli to jest pod Window, to jest również dostępny globalnie, czyli możemy tutaj napisać po prostu
hello. To będzie nam kierowało na funkcję, która znajduje się tutaj, a para nawiasów okrągłych to wykona,
więc jeżeli teraz tutaj odświeżę. Zobaczymy, najpierw firstName is nor defined, więc ten błąd nam zatrzymał
wykonywanie dalszego kodu, więc to wykomentuje. Odświeżam i Cześć Maciej Kowalski zostało tutaj jak
najbardziej wyświetlone co jest jednak bardzo ważne to jak widzisz ta funkcja wyświetliła Maciej Kowalski,
bo tutaj miała dostęp do firstName, zdefiniowanego tutaj wewnątrz, czyli w tym skrypcie nie mamy dostępu
do firstName,
ale kiedy wywołamy hello, to mamy dostęp do tej zmiennej, no i teraz mógłbyś się zastanowić, co by było gdybyśmy
tutaj stworzyli zmienną firstName.
Możemy to zrobić, bo w globalnym zakresie nie ma takiej zmiennej, ona jest tutaj ukryta w funkcji init, więc
wpiszemy sobie tutaj firstName np. Tomasz i wywołujemy funkcję hello, która kieruje na tę funkcję, a ta funkcja
jak wiesz odwołuje się właśnie do firstName, które wcześniej musi być zdefiniowane, więc zobaczymy czy
zostanie wywołane Maciej czy może jednak Tomasz? Sprawdźmy.
I jak widzisz, znowu jest to Maciej, czyli z tej lekcji, z tego przykładu zapamiętaj tyle, że funkcja ma dostęp
do zmiennych w miejscu, gdzie została zdefiniowana. Ta funkcja jest definiowana tutaj, więc ma dostęp do
zmiennych, które są w jej zakresie, czyli tych które są tutaj w funkcji init, a także do funkcji i zmiennych
globalnych. Natomiast nie ma znaczenia gdzie ona została wywołana. Została wywołana tutaj i nie sprawdza sobie
tutaj żadnej zmiennej firstName, bo ona miała dostęp do tej zmiennej.
Łatwo to można zobaczyć właśnie w miejscu gdzie się funkcja znajduje.
Jeżeli taka zmienna jest tutaj zdefiniowana to to oznacza, że do niej będzie miała właśnie dostęp ta
funkcja.
Takie zjawisko nazywa się w języku JavaScript domknięciem lub też z angielskiego closure i będę jeszcze
o tym mówił w drugiej części tego kursu JavaScript w praktyce.
Zakres zmiennych 1 · 1 min
function init() {
var firstName = "Maciej";
function sayHello(text) {
var lastName = "Kowalski";
console.log("Cześć, " + firstName + " " + lastName);
}
window.hello = sayHello;
}
init();Zakres zmiennych 2 · 10 min
// console.log(firstName);
var firstName = "Tomasz";
hello();Zakres zmiennych 1 · 10 min
function init() {
var firstName = "Maciej";
function sayHello(text) {
var lastName = "Kowalski";
console.log("Cześć, " + firstName + " " + lastName);
}
window.hello = sayHello;
}
init();