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 zobaczysz, jak działają parametry funkcji, które są niezwykle istotne w kontekście dynamizowania
kodu, a więc, aby funkcja mogła w różnych warunkach wykonywać dla nas różne obliczenia czy zwracać różne
dane będziemy musieli ją sparametryzować i później podawać jej różne argumenty.
Dlatego teraz przejdziemy od razu do kodu i chciałbym utworzyć funkcję, która będzie nam wracać kwadrat
przekazanej liczby.
Nazwiemy ją sobie square, czyli kwadrat i teraz wiesz, że normalnie ta funkcja wyglądałaby następująco i ona może
poprzez return coś zwrócić, ale właśnie tworząc funkcję, tutaj w nawiasach okrągłych możemy podawać
parametry, które chcemy później do tych funkcji przekazywać jako argumenty.
Teraz jak to wygląda?
Możemy tutaj podać dowolną liczbę parametrów.
I działa to tak, jak zmienne, jeżeli chcę sobie podać jakąś liczbę to mogę nazwać zmienną, czyli ten parametr
np. num, w ten sposób,
czyli ta konwencja nazewnictwa tutaj jest taka sama jak w przypadku zmiennych czy funkcji.
I teraz tutaj będę chciał z tej funkcji zwrócić to, co tutaj zostanie przekazane razy dokładnie to samo.
Zaraz ci to dokładnie wytłumaczę.
Czyli napiszemy return num razy
num, w ten sposób wiemy, że tutaj to zostanie najpierw pomnożone a później zwrócone.
I teraz, jeżeli tutaj zmienną nazwaliśmy num, to wywołując taką funkcję będziemy mogli tutaj dowolną rzecz
przekazać.
Nie ma znaczenia, dlatego że w JavaScript'cie nie mamy czegoś takiego jak deklaracja typu.
Czyli tutaj nie zadeklarowałem, czy to będzie numbers, string, object itd.
Będziemy to mogli oczywiście wewnątrz funkcji sprawdzić.
Ale teraz gdybym chciał zrobić console.log i wywołać funkcję, czyli square. Wiesz, że w console.log zostanie
wyświetlone to, co ta funkcja zwróci.
Skoro tutaj nazwałem parametr num, to znaczy że możemy go przekazać i przekażemy sobie
2.
Teraz działa to w ten sposób, że tutaj przez te nawiasy okrągłe wywołujemy tę funkcję przekazując jej
tutaj 2.
Po raz kolejny wspomnę ci o tym, że tu możemy przekazać jakąś zmienną, która przechowuje dwójkę i tak dalej.
Wstawiłem tutaj 2 i to oznacza tylko tyle że, ta funkcja zostanie wykonana i za tą zmienną zostanie podstawiona
2.
Czyli tutaj wewnątrz, num oraz num to będzie 2.
Ta funkcja zwróci nam w tym przypadku 2 razy 2, czyli 4 w console.log powinno się pojawić. Odświeżam i
dokładnie tak się stało i teraz mogę tutaj skorzystać znowu z tej funkcji, czyli square i podamy sobie
6.
Zostało nam zwrócone
36.
Jak zatem widzisz możemy tworzyć parametry i później kiedy przekazujemy jakieś wartości, to są one jakby
pod te zmienne podstawione, a te nazwy są tutaj oczywiście dowolne.
Wspomniałem ci, że taka funkcja może przyjmować dowolną liczbę parametrów, więc gdybyśmy chcieli stworzyć
kolejną funkcję, którą byśmy nazwali np. sum, czyli sumuj i chcemy zsumować dwie liczby, to możemy je dowolnie
nazwać np. a i b, jeżeli przy deklaracji takiej funkcji podam to w ten sposób, pierwszy parametr, po przecinku
drugi, to będę do nich miał dostęp
tutaj wewnątrz tej funkcji, więc możemy tutaj zwrócić
a plus b.
No i teraz gdybyśmy sobie z takiej funkcji sum skorzystali i wpiszemy sobie 10, po przecinku podajemy drugi
parametr np. 2.
Zostało nam zwrócone 12. Teraz to jest bardzo istotne, co by się stało, gdybyśmy nie podali sobie drugiego
parametru a, więc ja tutaj zadeklarowałem, jak widzisz, że mamy dwa parametry a i b i w wielu językach programowania
kiedy wywołujemy taką funkcję i nie podamy dwóch parametrów, to będziemy mieli błąd.
Nie w JavaScript'cie, widzisz że zostało zwrócone
Not a Number, czyli wartość, którą już znasz.
Dlaczego tak się stało?
Otóż dlatego, że jeżeli nie podamy parametru, to jest on uznawany za undefined.
Czyli jeżeli podałem a, czyli 10, ale nie podałem b, to b jest to undefined. Gdybyś zrobił console.log, b,
to byś zobaczył, że jest to undefined, czyli tutaj zrobiliśmy 10 plus undefined i to nam zwróciło
Not a Number i to z kolei zostało zwrócone przez tą funkcję.
Jeżeli z kolei podasz więcej parametrów, niż jest potrzebnych, nic się nie stanie.
Mieliśmy tutaj 10, 2 i jeśli podam sobie jeszcze 5, 6, czyli dodatkowe parametry,
nie możemy z nich skorzystać,
chyba, że byśmy tutaj napisali C i D, to wówczas one tam się znajdowały,
ale jeżeli tak, to podamy, nie ma problemu, również 12 zostanie zwrócone, bo ta funkcja korzysta tylko z
tych dwóch parametrów.
I jeszcze taka różnica między parametrami, a argumentami. Często jest to używane naprzemiennie.
Natomiast różnica jest subtelna i parametry są to te zmienne, które zadeklarowaliśmy czyli a oraz b są
to parametry, ale w momencie kiedy wywołujemy funkcje i podajemy jej prawdziwe dane, to te dane nazywamy
argumentami funkcji.
Możesz to zapamiętać, nie jest to bardzo istotne, natomiast często naprzemiennie się go używa.
Teraz chce ci pokazać jedną bardzo ważną rzecz. Otóż czy parametry są przekazywane poprzez kopiowanie
czy poprzez referencje?
Jak możemy to sprawdzić?
Może ja sobie tutaj usunę tę funkcję, którą mieliśmy.
Zostawimy sobie funkcję square albo może stworzymy nową funkcję,
którą nazwiemy sayHello,
tak będzie chyba najprościej.
I ona tutaj będzie przyjmować tekst. Powiedzmy, że w ten sposób i będzie ona nam robić w konsoli
Witaj
i do tego będziemy chcieli dodać text.
W ten sposób możemy sobie to sparametryzować.
Jeżeli teraz wywołamy sayHello, napiszemy Maciej, to będzie Witaj
Maciej. Natomiast stworzę sobie zmienną, którą nazwę text.
Możemy to zrobić w ten sposób, jeżeli ta nazwa będzie dokładnie taka sama jak ta, to nie ma znaczenia,
ale mogę ją nazwać np. name albo firstName.
Napiszemy Tomasz i teraz będę chciał taką funkcję wywołać tutaj, czyli sayHello do console.log'a,
to co ona zwróci,
będziemy chcieli wyświetlić, chociaż ona w zasadzie nic nie zwraca, więc zróbmy tutaj return, w ten sposob.
To, co ona zwróci zostanie podstawiane w console.log.
No i tutaj przekażemy firstName.
Odświeżam. Możesz się domyślić Witaj Tomasz.
Tylko teraz pytanie jest takie. Czy ta wartość Tomasz została tutaj skopiowana, w to miejsce, czy została
wystawiona?
Najprościej możemy to sprawdzić odwołując się do text równa się np. Piotr i co to oznacza?
Otóż, jeżeli wywołamy taką funkcję i przekazujemy tutaj firstName, czyli tą zmienną. Tam zostanie przekazana
ta wartość Tomasz, czyli w to miejsce.
Więc możemy sobie zadać pytanie, czy jeżeli text, czyli tą zmienną nadpiszemy Piotrem, to czy firstName się
nam zmieni. No i to możemy sprawdzić wpisując tutaj console.log firstName, czyli po wywołaniu tej funkcji
zobaczymy, czy ta zmienna zostanie zmieniona.
Odświeżam. No i jak widzisz mamy tutaj Witaj Piotr, a tutaj mamy ciągle Tomasz, czyli w tym miejscu nadpisałem sobie
tekst Piotr, to zostało tutaj zwrócone do console.log'a, ale nie zostało zmienione tutaj, a więc oznacza
to tylko tyle, że typy prymitywne są przekazywane do takiej funkcji poprzez kopiowanie.
Dokładnie tak samo, jak bym tutaj napisał, na przykład lastName równa się firstName.
To wiesz, że tutaj
zostanie Tomasz po prostu skopiowany.
Dlaczego jest to ważne?
Otóż dlatego, że jeżeli teraz utworzymy tutaj obiekt, który nazwę person i będzie on miał firstName Tomasz.
Oraz last name np. Kowalski.
No i będziemy chcieli ten obiekt przekazać, to możemy zakończyć średnikiem w to miejsce.
Nazwijmy sobie zmienną obj, jak obiekt.
Oczywiście, to nie ma znaczenia i będziemy chcieli tutaj się odwołać do tego obiektu.
Czyli wiesz, że person.firstName. W naszym przypadku person, który przekażemy tutaj mam nadzieję,
że nie jest dla ciebie zbyt zagmatwane.
Tutaj wywołuje funkcję przekazując jej person, czyli to co mamy tutaj wewnątrz funkcji będzie to dostępne
pod obliczaj, bo tak sobie to nazwałem, mógłbym to nazwać oczywiście person, ale tak to nazwałem i teraz
tutaj mogę się odwołać do obliczaj firstName plus spacja i do tego chcę sobie dodać obliczaj lastName, czyli
tutaj po prostu będę chciał opisać Witaj
Tomasz Kowalski. Tak się do tego odwołamy.
Znowu nam to zadziała poprawnie.
Ale teraz jest takie pytanie, skoro wiesz, że obiekty są przekazywane przez referencje, ja już ci o tym
mówiłem, że gdybyśmy utworzyli person2, w ten sposób i przypisali person1, to on nie jest tutaj kopiowany
i gdybyśmy się odwołali do person2.firstName, to tak naprawdę zmienimy to w tym miejscu.
No i właśnie pytanie, czy tutaj jest to przekazywane przez referencje czy nie.
Możemy to w bardzo prosty sposób sprawdzić. Jeżeli napiszemy sobie obiekt, czyli odwołamy się do tego, co mamy
tutaj, a tu person zostało przekazane i chcę go nadpisać jakimś pustym obiektem. To sobie może wykomentuje, żebyśmy nie mieli
błędu, że chcemy się odwołać do pustych właściwości. Wywołuje funkcję, odwołajmy się do person, persom
nadal przechowuje to wszystko.
Czyli jeżeli tutaj próbowałem napisać ten obiekt, to nam się nie udało, ale zobacz, co stanie się w momencie
kiedy ja tutaj odwołam się do jakichś właściwości tego obiektu, czyli np. firstName i przepisze tutaj
Piotr. Oczywiście możesz się domyśleć, że tutaj zostanie to podstawione i mamy Witaj Piotr Kowalski, ale
jeżeli odwołam się do person, to widzisz, że firstName również zostało zmienione i teraz może ci się to
wydawać zagmatwane, ale generalnie zasada działania jest taka, że jeżeli przekazujemy tutaj obiekt i chciałbym
ten obiekt nadpisać, to jeżeli tutaj przypisze do niego cokolwiek innego, to tak naprawdę nadpisuję tylko
lokalną zmienną obj, która tutaj się znajduje.
Natomiast, jeżeli już się odwołam do jakiejś właściwości tego obiektu i je zmienię, to wtedy odwołuję się do
niego przez referencje i skoro person mamy tutaj. Tutaj został przekazany do tej funkcji.
Nie ma znaczenia, gdzie ona jest zadeklarowana,
to jeżeli odwołam się do firstName to faktycznie to zmienia.
Ja mówię tutaj o obiekcie, ale niech nie zmyli cię taki zapis, bo ja mówiłem, że to jest tzw. Object Literal,
ale w JavaScript'cie prawie wszystko jest obiektem.
Jeżeli byśmy przekazywali np. tablicę to będzie podobnie. Jeżeli napiszę obj,
w ten sposób, to nie zresetuje tej tablicy, ale jeżeli napiszę tutaj obj na przykład length 0, to tablica,
która zostanie tutaj przekazana, faktycznie zostanie zresetowania, bo tablica jak już wiesz, jest obiektem,
więc chciałbym, abyś taką różnicę zapamiętał i ja może zostawię to na takim etapie w plikach, abyś mógł się
jeszcze z tym zapoznać.
Parametry funkcji · 1 min
function square(num) {
return num * num;
}
var firstName = "Tomasz";
var person = {
firstName: "Tomasz",
lastName: "Kowalski"
};
function sayHello(obj) {
obj.firstName = "Piotr";
return "Witaj, " + obj.firstName + " " + obj.lastName;
}
console.log(sayHello(person));