Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00167 013961 11052366 na godz. na dobę w sumie
Head First JavaScript. Edycja polska - książka
Head First JavaScript. Edycja polska - książka
Autor: Liczba stron: 624
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-1548-3 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> javascript - programowanie
Porównaj ceny (książka, ebook, audiobook).

Poznaj język JavaScript w niekonwencjonalny
i zadziwiająco skuteczny sposób!

Dziś statyczne witryny WWW giną w ogromnej masie podobnych sobie stron, przy braku zainteresowania współczesnych użytkowników sieci. Aby się wyróżnić, trzeba zaproponować oglądającym coś innego niż tylko ładnie sformatowany tekst i schludną grafikę. Jednym z pomysłów na zwiększenie atrakcyjności witryny WWW jest wprowadzenie na nią elementów interaktywnych. Istnieje wiele rozwiązań służących do tworzenia takich elementów. Jednym z najczęściej wykorzystywanych jest JavaScript. Ten interpretowany po stronie przeglądarki język pozwala między innymi na kontrolowanie niemal wszystkich elementów HTML w oparciu o obiektowy model dokumentu (DOM), obsługę zdarzeń generowanych przez użytkownika i weryfikację poprawności danych wprowadzanych do formularza.

Dzięki książce 'Head First JavaScript. Edycja polska' poznasz JavaScript w nietypowy, a przy tym bardzo skuteczny sposób. Ponieważ została ona napisana w oparciu o najnowsze teorie uczenia się, błyskawicznie przyswoisz sobie wiedzę o tym języku. Nauczysz się osadzać kod JavaScript w dokumentach HTML, przetwarzać dane i sterować wykonywaniem skryptu za pomocą konstrukcji warunkowych. Dowiesz się, jak korzystać z obiektowego modelu dokumentu, tworzyć i obsługiwać pliki cookie oraz procedury obsługi zdarzeń. Poznasz także techniki programowania obiektowego i sposoby wykrywania czy usuwania błędów. Przeczytasz również o technologii AJAX, opierającej się na języku JavaScript.

Twój czas jest cenny -- wykorzystaj go na poznanie JavaScript z pomocą nowoczesnych metod nauki!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Head First JavaScript. Edycja polska Autor: Michael Morrison T³umaczenie: Piotr Rajca ISBN: 978-83-246-1548-3 Tytu³ orygina³u: Head First JavaScript (Head First) Format: 200x230, stron: 624 Poznaj jêzyk JavaScript w niekonwencjonalny i zadziwiaj¹co skuteczny sposób! Dziœ statyczne witryny WWW gin¹ w ogromnej masie podobnych sobie stron, przy braku zainteresowania wspó³czesnych u¿ytkowników sieci. Aby siê wyró¿niæ, trzeba zaproponowaæ ogl¹daj¹cym coœ innego ni¿ tylko ³adnie sformatowany tekst i schludn¹ grafikê. Jednym z pomys³ów na zwiêkszenie atrakcyjnoœci witryny WWW jest wprowadzenie na ni¹ elementów interaktywnych. Istnieje wiele rozwi¹zañ s³u¿¹cych do tworzenia takich elementów. Jednym z najczêœciej wykorzystywanych jest JavaScript. Ten interpretowany po stronie przegl¹darki jêzyk pozwala miêdzy innymi na kontrolowanie niemal wszystkich elementów HTML w oparciu o obiektowy model dokumentu (DOM), obs³ugê zdarzeñ generowanych przez u¿ytkownika i weryfikacjê poprawnoœci danych wprowadzanych do formularza. Dziêki ksi¹¿ce „Head First JavaScript. Edycja polska” poznasz JavaScript w nietypowy, a przy tym bardzo skuteczny sposób. Poniewa¿ zosta³a ona napisana w oparciu o najnowsze teorie uczenia siê, b³yskawicznie przyswoisz sobie wiedzê o tym jêzyku. Nauczysz siê osadzaæ kod JavaScript w dokumentach HTML, przetwarzaæ dane i sterowaæ wykonywaniem skryptu za pomoc¹ konstrukcji warunkowych. Dowiesz siê, jak korzystaæ z obiektowego modelu dokumentu, tworzyæ i obs³ugiwaæ pliki cookie oraz procedury obs³ugi zdarzeñ. Poznasz tak¿e techniki programowania obiektowego i sposoby wykrywania czy usuwania b³êdów. Przeczytasz równie¿ o technologii AJAX, opieraj¹cej siê na jêzyku JavaScript. • Podstawowe elementy JavaScript • Praca ze zmiennymi • Interakcja z przegl¹dark¹ • Wyra¿enia warunkowe i pêtle • Organizacja kodu i korzystanie z funkcji • Obiektowy Model Dokumentu • Obiekty w JavaScript • Testowanie skryptów • Wykorzystanie JavaScript w technologii AJAX Twój czas jest cenny — wykorzystaj go na poznanie JavaScript z pomoc¹ nowoczesnych metod nauki! Spis treści (podsumowanie) 1 2 3 4 5 6 7 8 9 10 11 12 Wprowadzenie Interaktywna WWW. W odpowiedzi na wirtualny świat Przechowywanie danych. Wszystko ma swoje miejsce Poznajemy klienta. W głąb przeglądarki Podejmowanie decyzji. Jeśli droga się rozwidla, nie wahaj się skręcić Pętle. Ryzykując powtórzeniem Funkcje. Redukuj i używaj wielokrotnie Formularze i sprawdzanie poprawności danych. Aby użytkownik powiedział nam wszystko Modyfikacje stron WWW. Krojenie i przyprawianie HTML-a przy użyciu DOM Ożywianie danych. Obiekty jako Frankendane Tworzenie własnych obiektów. Zrób to po swojemu, używając własnych obiektów Zabijaj pluskwy — na śmierć! Dobre skrypty na złej drodze Dynamiczne dane. Szybkie i wrażliwe aplikacje internetowe Skorowidz Spis treści 19 31 61 111 159 211 263 307 359 407 461 495 545 605 Spis treści (teraz na poważnie) W Wprowadzenie Twój mózg koncentruje się na JavaScripcie. Siedzisz, próbując się czegoś nauczyć, ale Twój mózg twierdzi, że cała ta nauka nie jest ważna. Twój mózg twierdzi: „Lepiej zostawić miejsce na jakieś ważne rzeczy, takie jak to, których dzikich zwierząt należy unikać albo czy jeżdżenie nago na snowboardzie jest dobrym pomysłem, czy nie”. W jaki zatem sposób możesz przekonać swój mózg, by uznał, że poznanie JavaScriptu to dla Ciebie kwestia życia lub śmierci? Dla kogo jest ta książka? Wiemy, co sobie myślisz Metapoznanie Oto, co możesz zrobić, aby zmusić swój mózg do posłuszeństwa Przeczytaj to Zespół recenzentów Podziękowania 20 21 23 25 26 28 29 5 Spis treści 1 Interaktywna WWW W odpowiedzi na wirtualny świat Czy męczy Cię już myślenie o WWW w kategoriach statycznych stron? To już widziałem i przerobiłem. Takie rzeczy zazwyczaj nazywają książkami. Trzeba przyznać, że doskonale się one nadają do czytania i nauki, i w ogóle są super. Ale… nie są interaktywne. To samo dotyczy także stron WWW, jeśli nie uzyskają one nieznacznej pomocy ze strony języka JavaScript. Pewnie, że można przesłać formularz i może nawet zastosować tu i tam kilka trików, używając w tym celu umiejętnie napisanego kodu HTML i CSS, jednak takie rozwiązania nie są w stanie „ożywić” martwych — statycznych stron WWW. Prawdziwa interaktywność wymaga znacznie większego wkładu intelektualnego i nakładu pracy, jednak zapewnia efekty, które zwrócą się z nawiązką. Użytkownicy (WWW) mają swoje potrzeby To jakby rozmowa ze ścianą — całkowity brak reakcji A JavaScript odpowiada Światła, kamera, interakcja! Użyj znacznika script , by dać przeglądarce znać, że piszesz kod JavaScript Twoja przeglądarka WWW poradzi sobie z kodem HTML, CSS i JavaScript Najlepszy wirtualny przyjaciel mężczyzny… potrzebuje TWOJEJ pomocy Zapewnianie interaktywności iGłazowi Utworzenie strony WWW iGłazu Test Zdarzenia JavaScript: udzielamy głosu iGłazowi Informowanie użytkownika przy wykorzystaniu funkcji Dodanie powitania A teraz zadbamy o to, by iGłaz stał się naprawdę interaktywny Interakcja jest komunikacją DWUstronną Dodajemy funkcję do pobrania imienia użytkownika Błyskawiczna powtórka: Co się przed chwilą stało? Testujemy iGłaz w wersji 1.0 32 33 34 36 41 42 45 46 47 47 48 49 50 52 53 54 57 58 6 Spis treści 2 Przechowywanie danych Wszystko ma swoje miejsce W praktyce często nie dostrzegamy znaczenia, jakie ma posiadanie miejsca do przechowywania swoich rzeczy. Korzystając z języka JavaScript, na pewno zwrócimy na to uwagę. W tym przypadku nie mamy bowiem luksusu posiadania osobnej garderoby lub garażu na trzy samochody. W JavaScripcie wszystko musi mieć swoje miejsce, a Twoim zadaniem jest zadbanie, by faktycznie tak się stało. W tym rozdziale będziemy się zajmować danymi oraz zagadnieniami, które ich dotyczą — jak je reprezentować, przechowywać oraz jak je odnaleźć, kiedy zostaną już gdzieś zapisane. Jako specjalista do spraw przechowywania danych w JavaScripcie będziesz w stanie zająć się dowolnym kodem, zapanować nad chaosem obecnym wśród używanych w nim danych, dzięki czemu będziesz mógł uporządkować go wedle swojej woli, korzystając przy tym z zalet wirtualnych etykiet i pojemników. Twoje skrypty mogą przechowywać dane Skrypty myślą w oparciu o typy danych Stałe zostają TAKIE SAME, wartości zmiennych mogą się ZMIENIAĆ Zmienne początkowo nie mają wartości Inicjalizacja zmiennej przy użyciu znaku = Stałe są odporne na zmiany A jak wyglądają nazwy? Dozwolone i niedozwolone nazwy zmiennych oraz stałych Nazwy zmiennych często są zapisywane według notacji CamelCase Planujemy stronę zamówienia dla Donalda Pierwsze podejście do obliczeń w formularzu zamówienia Inicjuj swoje dane albo… NaN NIE jest liczbą Nie tylko liczby można dodawać parseInt() oraz parseFloat() — konwersja łańcuchów znaków na liczby Dlaczego w zamówieniu pojawiają się dodatkowe pączki? Donald odkrywa „szpiegostwo ciastkarskie” Użyj metody getElementById(), by pobrać dane z formularza Weryfikacja danych w formularzu Staraj się, by interfejs użytkownika był intuicyjny 6 z nadzieniem 3 z lukrem Odbierze Grzesiek za 20 minut 62 63 68 72 73 74 78 79 80 84 86 89 90 92 93 94 98 99 100 105 7 W głąb przeglądarki 3 Poznajemy klienta Czasami kod JavaScript musi „wiedzieć”, co się dzieje w świecie naokoło niego. Twoje skrypty mogą początkowo być tworzone jako kod umieszczany bezpośrednio w stronach WWW, jednak w ostateczności i tak będą istnieć i działać w świecie kreowanym przez przeglądarkę WWW, nazywaną także klientem. „Sprytne” skrypty często będą potrzebowały pewnych informacji o świecie, w którym „żyją”; w takich sytuacjach mogą zdobyć te dane, komunikując się z przeglądarką. Niezależnie od tego, czy jest to określenie wymiarów ekranu, czy też dostęp do jakiegoś przycisku przeglądarki, to utrzymując dobre stosunki z przeglądarką, skrypty mogą bardzo wiele zyskać. Tu zaczynamy! Koniec! Klienty, serwery i JavaScript Co przeglądarka może zrobić dla Ciebie? iGłaz musi reagować bardziej wyraziście Liczniki czasu kojarzą akcje z upływającym czasem Przerywanie działania licznika Tworzenie licznika czasu przy użyciu funkcji setTimeout() W zbliżeniu — funkcja setTimeout() Wiele rozmiarów ekranu, wiele skarg Użyj obiektu document, by określić szerokość okna przeglądarki Skorzystaj z obiektu document, by odczytać szerokość okna klienta Określanie wymiarów obrazka iGłazu Wielkość iGłazu należy dostosować do strony W momencie zmiany wielkości okna zgłaszane jest zdarzenie onresize Zdarzenie onresize skaluje obrazek iGłazu Czy myśmy się już spotkali? Rozpoznawanie użytkownika Każdy skrypt ma swój cykl życiowy Ciasteczka mogą istnieć dłużej niż cykl życia skryptu Ciasteczka mają nazwę i przechowują wartość… poza tym mogą wygasnąć Twój kod JavaScript może istnieć POZA Twoją stroną WWW Przywitaj użytkownika ciasteczkiem Teraz funkcja greetUser bazuje na ciasteczkach Nie zapomnij o zapisaniu ciasteczka Ciasteczka mają wpływ na bezpieczeństwo przeglądarek Świat bez ciasteczek Porozmawiaj z użytkownikiem, to lepsze niż nic… 112 114 116 118 119 120 121 125 126 127 128 129 133 134 136 137 138 143 145 146 147 148 150 152 155 Spis treści 8 Spis treści 4 Podejmowanie decyzji Jeśli droga się rozwidla, nie wahaj się skręcić Życie polega na podejmowaniu decyzji. Stanąć czy jechać, mieszać czy wstrząsać, iść na ugodę czy do sądu… Tak naprawdę bez możliwości podejmowania decyzji nic nigdy nie udałoby się zrobić. To samo dotyczy JavaScriptu — decyzje pozwalają skryptom dokonywać wyboru pomiędzy różnymi możliwymi wynikami. To właśnie podejmowanie decyzji tworzy „historię” naszego skryptu, a swoją historię mają wszystkie skrypty, nawet te najbardziej prozaiczne. Czy więrzę w to, co wpisał użytkownik, i bez wahania zarezerwuję mu uczestnictwo w ekspedycji badawczej Białowieży? A może bardzo dokładnie sprawdzę wpisane informacje, by nie okazało się, że tak naprawdę użytkownik chciałby jedynie dojechać autobusem w okolice Białowieży? Sam musisz podjąć decyzję i dokonać wyboru! Szczęśliwy uczestniku, prosimy na scenę! „Jeśli” to prawda, to coś zrób Instrukcja if przetwarza warunek, a następnie wykonuje operację Użyj instrukcji if, by wybrać jedną z dwóch opcji Instrukcja if pozwala wybierać spośród wielu opcji Dodawanie klauzuli else do instrukcji if Przebiegiem zdarzeń sterują zmienne Brakuje jednak części historii Składanie operacji w JavaScripcie Męczy Cię podejmowanie decyzji przy użyciu instrukcji if/else? Instrukcję if można umieścić wewnątrz innej instrukcji if Twoje funkcje kontrolują działanie stron Pseudokod pozwala naszkicować ogólny obraz przygody Nierówność kreskowego ludzika != Ech, Nie mam ci nic do powiedzenia… Podejmowanie decyzji z wykorzystaniem operatorów porównania Komentarze, puste miejsca i dokumentacja Komentarze w JavaScripcie zaczynają się od znaków // Zakres i kontekst — gdzie „żyją” dane Sprawdź, gdzie są rozmieszczone zmienne w naszej przygodzie Gdzie żyją moje dane? Jedna z pięciu Zagnieżdżanie instrukcji if/else może się stać skomplikowane Instrukcje switch udostępniają wiele opcji Poznajemy szczegóły instrukcji switch Testowanie nowej wersji Przygody kreskowego ludzika 160 162 163 165 166 167 170 171 172 178 179 181 182 186 187 188 190 191 193 194 195 198 199 201 202 207 9 Spis treści 5 Dostępne Pętle Ryzykując powtórzeniem Niektórzy mówią, że powtórzenia to podstawa sukcesu. Oczywiście, że robienie wciąż nowych i interesujących rzeczy jest ekscytujące, lecz jednak codzienne życie składa się z czynności, które wielokrotnie powtarzamy. Maniakalne czyszczenie rąk, nerwowe tiki bądź klikanie przycisku Odpowiedz wszystkim po odebraniu każdego dziwacznego lub śmiesznego e-maila! No dobrze, może w rzeczywistości powtórzenia nie zawsze są takie znowu wspaniałe. Niemniej w świecie JavaScriptu powtórzenia mogą być niesłychanie przydatne i użyteczne. Sam nie wiesz, jak często pojawia się potrzeba kilkakrotnego wykonania pewnego fragmentu kodu… I właśnie w takich sytuacjach w pełni można docenić zalety pętli. Gdyby nie one, musiałbyś spędzać bardzo dużo czasu, wielokrotnie kopiując i wklejając ten sam fragment kodu. „X” wskazuje miejsce Cały czas déja vu — pętle for Poszukiwanie skarbów z pętlą for Anatomia pętli for Mandango — wyszukiwarka miejsc dla prawdziwych macho Najpierw sprawdzamy dostępność miejsc Pętle, HTML i dostępność miejsc Fotele są zmiennymi Tablice gromadzą wiele danych Wartości tablicy są zapisywane wraz z kluczami Od JavaScriptu do HTML-a Wizualizacja miejsc na stronie Mandango Test: odnajdywanie pojedynczych wolnych miejsc Co za dużo, to niezdrowo — pętle nieskończone Pętle zawsze muszą mieć warunek zakończenia (albo nawet dwa!) Przerwa w działaniu Odkrywamy operatory logiczne Powtórzenia do skutku… dopóki warunek jest spełniony Analiza pętli while Zastosowanie odpowiedniej pętli do konkretnego zadania Modelowanie danych reprezentujących miejsca w kinie Tablica tablic — tablice dwuwymiarowe Dwa klucze zapewniają dostęp do tablicy dwuwymiarowej Dwuwymiarowe Mandango Cała sala miejsc dla prawdziwych macho 212 213 214 215 216 217 218 219 220 221 225 226 231 232 233 234 240 244 245 247 253 254 255 257 260 seat_avail.png Zajęte Wybrane seat_unavail.png seat_select.png 10 Spis treści 6 Funkcje Redukuj i używaj wielokrotnie Gdyby w świecie JavaScriptu zaistniał jakiś ruch środowiskowy, to zapewne na jego czele stanęłyby funkcje. Funkcje pozwalają na pisanie bardziej efektywnego kodu i sprawiają, że łatwiej można go wielokrotnie używać. Funkcje są zorientowane na wykonywanie konkretnych zadań i znacząco ułatwiają organizację kodu. Wygląda to jak całkiem dobry życiorys! W praktyce niemal wszystkie skrypty, może za wyjątkiem tych najprostszych, mogą skorzystać na reorganizacji kodu i zastosowaniu funkcji. Choć trudno jest ocenić znaczenie i wpływ przeciętnej funkcji, to jednak należy zaznaczyć, że odgrywają one znaczącą rolę w staraniach, by skrypty były możliwie jak najbardziej przyjazne dla środowiska. Matka wszystkich problemów Funkcje jako narzędzia do rozwiązywania problemów Tworzenie funkcji w praktyce Funkcje, które już poznałeś Lepsza klimatyzacja dzięki większej ilości danych Przekazywanie informacji do funkcji Argumenty funkcji jako dane Funkcje eliminują powtarzający się kod Tworzenie funkcji określającej status miejsc Funkcja setSeat() jeszcze bardziej poprawia kod aplikacji Mandango Znaczenie informacji zwrotnych Zwracanie danych z funkcji Wiele szczęśliwych wartości wynikowych Odczyt statusu miejsca Prezentacja statusu miejsca Możemy połączyć funkcję z obrazkiem Powielanie kodu nigdy nie jest dobre Separacja funkcjonalności od zawartości Funkcje są zwykłymi danymi Wywołania i odwołania do funkcji Zdarzenia, funkcje zwrotne i atrybuty HTML Określanie procedur obsługi zdarzeń przy użyciu odwołań do funkcji Literały funkcyjne spieszą z odsieczą Czym jest kojarzenie ? Struktura strony HTML 264 266 267 268 271 272 273 274 277 279 281 282 283 287 288 289 290 291 292 293 297 298 299 300 303 11 Spis treści 7 Formularze i sprawdzanie poprawności danych Aby użytkownik powiedział nam wszystko Nie musisz być ani szczególnie grzeczny, ani chytry, by pobierać od użytkowników dane, korzystając z możliwości, jakie zapewnia JavaScript. Nie ma natomiast żadnych wątpliwości co do tego, że musisz zachować przy tym dużą ostrożność i uwagę. Ludzie wykazują dziwną tendencję do popełniania błędów, co oznacza, że nie możesz z góry zakładać, iż informacje podawane przez użytkowników będą precyzyjne bądź prawidłowe. I tu do akcji wkracza JavaScript. Przekazując informacje wpisane w polach formularza do odpowiedniego kodu napisanego w tym języku, i to bezpośrednio po ich podaniu, możesz nie tylko poprawić niezawodność aplikacji, lecz także nieco odciążyć serwer. Musimy oszczędzać cenną przepustowość łączy na ważniejsze rzeczy, takie jak wideo z zapierającymi dech w piersiach wyczynami kaskaderskimi lub urocze zdjęcia naszego ulubionego zwierzaka. Formularz rejestracyjny Banerolotu Kiedy HTML nie wystarcza Dostęp do danych formularzy Weryfikacja danych podąża za ciągiem zdarzeń Zdarzenia onblur — tracimy ostrość Możesz używać okienka informacyjnego do wyświetlania komunikatów o błędach Weryfikacja pól w celu sprawdzenia, czy mamy coś więcej niż „nic” Weryfikacja bez wkurzających okienek dialogowych Subtelniejsze metody weryfikacji danych Wielkość ma znaczenie… Weryfikacja długości danych Weryfikacja kodu pocztowego Weryfikacja daty Niezwykłe wyrażenia regularne Wyrażenia regularne definiują poszukiwane wzorce Metaznaki reprezentują więcej niż jeden znak Tajniki wyrażeń regularnych — kwantyfikatory Weryfikacja danych przy użyciu wyrażeń regularnych Dopasowywanie określonej liczby powtórzeń Eliminacja trzycyfrowego roku przy użyciu tego… lub tamtego… Niczego nie zostawiajmy przypadkowi Czy teraz mnie słyszysz? Weryfikacja numeru telefonu Masz wiadomość — weryfikacja adresów e-mail Wyjątek jest regułą Dopasowywanie opcjonalnych znaków ze zbioru Tworzenie funkcji weryfikującej adres e-mail 309 310 311 313 314 315 319 320 321 323 324 329 334 336 337 339 340 344 347 349 350 351 352 353 354 355 y reklamowe l o t … podnieb n e b a n r e o e r B a n 12 Spis treści 8 Modyfikacje stron WWW Krojenie i przyprawianie HTML-a przy użyciu DOM Uzyskanie kontroli nad zawartością stron WWW dzięki wykorzystaniu JavaScriptu w dużym stopniu przypomina pieczenie. Nie wiąże się co prawda z takim samym bałaganem… jednak z drugiej strony nie daje w efekcie tak smakowitych rezultatów. Niemniej masz pełny dostęp do składników HTML-a tworzących stronę WWW, a co więcej — masz możliwość modyfikowania przepisu tej strony. A zatem JavaScript pozwala na modyfikowanie kodu HTML strony i dostosowywanie go do własnych potrzeb, co daje bardzo ciekawe możliwości. A wszystko to dzięki kolekcji standardowych obiektów, określanej mianem obiektowego modelu dokumentu (w skrócie DOM, od angielskich słów Document Object Model). Funkcjonalny, lecz niezgrabny — interfejs użytkownika ma znaczenie Opisy scen bez okienek dialogowych Dostęp do elementów HTML Bliższe spotkanie z wewnętrznym HTML-em Aby zobaczyć lasy i drzewa: obiektowy model dokumentu (DOM) Twoja strona jest kolekcją węzłów DOM Poruszanie się po drzewie DOM przy użyciu właściwości Modyfikowanie węzła tekstowego przy wykorzystaniu DOM Przygoda standaryzowana Projektujemy większe i lepsze opcje Rozważania nad zastępowaniem węzłów tekstowych Funkcja zastępująca tekst w węźle Dynamiczne opcje nawigacyjne to świetna rzecz Interaktywne opcje decyzyjne są jeszcze lepsze Kwestia stylu: CSS i DOM Podmienianie stylów Klasowe opcje Test stylizowanych opcji decyzyjnych Problemy z opcjami — pusty przycisk Modyfikacja stylów wedle zamówienia Żadnych niepotrzebnych opcji Więcej opcji, większa złożoność Śledzenie drzewa decyzyjnego Przekształć historię swoich decyzji na kod HTML Produkcja kodu HTML Śledzenie przebiegu przygody 360 361 363 364 369 370 373 376 381 383 384 385 386 387 388 389 390 391 392 393 395 396 398 399 400 403 13 Document html body head p Stoisz strong w samym (cid:258)rodku lasu. sam Spis treści 9 Ożywianie danych Obiekty jako Frankendane Obiekty JavaScriptu nie są tak makabryczne, jak dobry lekarz mógłby przypuszczać. Niemniej są ciekawe, gdyż łączą różne elementy języka w jedną całość, która ma większe możliwości niż suma jej składowych. Obiekty łączą dane z akcjami, tworząc w ten sposób nowy typ danych, który w znacznie większej mierze niż opisane wcześniej typy przypomina coś „żywego”. W efekcie możemy stworzyć tablice, które same będą potrafiły posortować swoją zawartość, łańcuchy znaków dysponujące możliwością samodzielnego przeszukiwania swojej treści, a skryptom może wyrosnąć sierść i mogą zacząć wyć do księżyca! No dobra, te dwie ostatnie rzeczy nie są możliwe, ale rozumiesz już, o co chodzi. JavaScriptowa impreza Dane + akcje = obiekt Obiekt jest właścicielem danych W odwołaniach do składowych obiektu używamy kropki Niestandardowe obiekty rozszerzają język JavaScript Tworzenie własnego niestandardowego obiektu Co jest w konstruktorze? Powołujemy do życia obiekty blogu Potrzeba sortowania Obiekt daty w JavaScripcie Wyliczanie czasu Ponowna analiza zagadnienia dat w blogu Obiekt w obiekcie Konwersja obiektów na łańcuchy znaków Pobieranie konkretnych informacji o dacie Tablice jak obiekty Sortowanie tablic wedle własnych potrzeb Łatwiejsze sortowanie dzięki literałom funkcyjnym Przeszukiwanie wpisów w blogu Przeszukiwanie zawartości łańcucha znaków indexOf() Przeszukiwanie tablicy blogu Teraz działa także wyszukiwanie! Obiekt Math jest obiektem organizacyjnym Generowanie liczb losowych przy użyciu metody Math.random() Zamiana funkcji na metodę Przedstawiamy piękny nowy obiekt Blog Jakie są korzyści użycia obiektów na stronie MagicznaKostka? 408 409 410 411 415 416 417 418 423 424 425 426 427 430 431 434 435 436 439 441 442 445 448 450 455 456 457 Dane var kto; var co; var kiedy; var gdzie; + = Akcje function prezentuj(co, kiedy, gdzie) { ... } function dostarcz(kto) { ... } Obiekt function prezentuj (co, kiedy, gdzie) { ... } function dostarcz(kto) { ... } var kto; var co; var kiedy; var gdzie; 14 Spis treści 10 Tworzenie własnych obiektów Zrób to po swojemu, używając własnych obiektów Gdyby to było takie łatwe, na pewno byś sobie z tym sam poradził. W świecie JavaScriptu nie ma gwarancji zwrotu poniesionych kosztów, jednak nikt nigdy nie będzie Ci bronił robić wszystkiego po swojemu. Niestandardowe obiekty w JavaScripcie są odpowiednikiem świetnej, wielkiej, gorącej, mistrzowskiej, okazyjnej promocji. To jeden niestandardowy kubek kawy! A dzięki własnym obiektom JavaScriptu możesz zaparzyć sobie kawę, która zrobi dokładnie to, co będziesz chciał — a wszystko to dzięki korzyściom, jakie zapewniają właściwości i metody. W efekcie powstaje obiektowy, nadający się do wielokrotnego stosowania kod, który rozszerza możliwości języka JavaScript… tylko i wyłącznie dla Ciebie! Ponowna analiza metod obiektu Blog Przeciążanie metod Klasy i instancje Instancje są tworzone na podstawie klasy Słowo kluczowe this zapewnia dostęp do właściwości obiektów Należą do jednej, działają we wszystkich — metody należące do klasy Korzystaj z prototypu, by operować na poziomie klasy Klasy, prototypy i MagicznaKostka Także właściwości klasowe są współdzielone Tworzenie właściwości klasowych przy użyciu prototypu Podpisane i dostarczone Metoda formatująca daty Rozszerzanie standardowych obiektów Zmodyfikowany obiekt daty = lepsza strona Reni Klasa może mieć swoją własną metodę Analiza funkcji porównującej wpisy Wywoływanie metody klasowej Jeden obraz jest wart tysiąca słów w blogu Dodawanie obrazków do blogu Dodawanie obrazków do strony MagicznaKostka Obiektowa strona blogu Klasa obiektu Blog Blog toString() Już mnie głowa rozbolała od zabaw tą nową kostką... 16 sierpnia 2008 toHTML() containsText() Blog toString() Znalazłam w internecie toHTML() układankę 7×7×7. O rany! Zabawa będzie... 21 sierpnia 2008 containsText() Blog toString() Spotkałam się z kilkoma innymi zapaleńcami, by porozmawiać o układaniu... 29 sierpnia 2008 toHTML() containsText() 462 463 464 465 466 467 468 469 474 475 477 480 481 482 483 485 486 487 488 490 492 15 Spis treści 11 Zabijaj pluskwy — na śmierć! Dobre skrypty na złej drodze Nawet najlepiej zaplanowany kod JavaScript może czasami zawieść. Kiedy tak się stanie, a kiedyś na pewno to nastąpi, to Twoim zadaniem będzie opanować nerwy i nie wpadać w panikę. Najlepsi programiści to nie tacy, którzy nigdy nie popełniają błędów — tacy są raczej kłamcami. Najlepsi programiści to tacy, którzy potrafią wytropić pluskwy i pozbyć się błędów, które sami popełnili. Co ważniejsze, najlepsi pogromcy pluskiew rozwijają dobre praktyki kodowania, które minimalizują niebezpieczeństwo popełniania najbardziej złośliwych i trudnych do wytropienia błędów. Z drugiej strony trochę prewencji nie zaszkodzi. Pamiętaj, że pluskwy pojawiają się zawsze, będziesz zatem potrzebował arsenału, by z nimi walczyć… Debugowanie w praktyce Przypadek wadliwego kalkulatora IQ Wypróbuj kod w różnych przeglądarkach Proste sposoby usuwania błędów Dzikie niezdefiniowane zmienne Przetwarzając wartości IQ Przypadek błędów w połączeniach z radiem Otwieranie dochodzenia Problem weryfikacji błędów składniowych (pluskwa nr 1) Uwaga na te łańcuchy znaków Cudzysłowy, apostrofy i konsekwencja Kiedy apostrof nie jest apostrofem, użyj odwrotnego ukośnika Nie tylko zmienne mogą być niezdefiniowane (pluskwa nr 2) Każdy jest zwycięzcą (pluskwa nr 3) Testowanie przy użyciu okienka dialogowego Obserwowanie zmiennych przy użyciu okienek dialogowych Zła logika może być przyczyną błędów Nikt nie wygrywa! (pluskwa nr 4) Przytłoczony ilością denerwujących okienek dialogowych Tworzymy własną konsolę do testowania skryptów Błędy najgorsze ze wszystkich: błędy czasu wykonywania programu Bestiariusz JavaScriptu Komentarze jako chwilowe wyłączniki kodu Niebezpieczeństwa związane ze zmiennymi-cieniami 496 497 498 501 505 507 508 509 510 511 512 513 514 516 517 518 520 524 525 527 534 535 538 540 16 Spis treści 12 Dynamiczne dane Szybkie i wrażliwe aplikacje internetowe W nowoczesnym internecie bardzo duże znaczenie ma szybkość i trafność reakcji — powszechnie oczekuje się, że strony będą błyskawicznie reagować na każdą zachciankę użytkownika. Albo przynajmniej marzą o tym niektórzy użytkownicy i twórcy aplikacji internetowych. Ważną rolę w realizacji tego marzenia odgrywa język JavaScript, stanowiący kluczowy element technologii o nazwie Ajax, zapewniającej możliwość dynamicznego modyfikowania zawartości i wyglądu stron WWW. Dzięki Ajaksowi strony WWW w znacznie większym stopniu przypominają standardowe aplikacje komputerowe, gdyż mogą szybko i dynamicznie pobierać oraz zapisywać dane, błyskawicznie odpowiadając na poczynania użytkownika i to bez przeładowywania stron. Pożądając dynamicznych danych MagicznaKostka sterowana danymi Ajax oznacza komunikację XML pozwala nam opisywać nasze dane po swojemu XML + HTML = XHTML XML i dane blogu Reni Ajax wzmacnia stronę MagicznaKostka XMLHttpRequest — JavaScript spieszy z pomocą GET czy POST? Użycie obiektu XMLHttpRequest Aby zrozumieć ajaksowe żądania Interaktywne strony zaczynają się od obiektu żądania Zawołaj mnie, kiedy skończysz Obsługa żądania… bezproblemowa DOM spieszy z pomocą Teraz strona MagicznaKostka jest w pełni zależna od swoich danych Niedziałające przyciski Przyciski potrzebują danych Usprawnienia oszczędzające czas blogera Zapisywanie danych blogu Także PHP ma swoje potrzeby Przekazywanie danych do skryptu PHP Do rzeczy — przesyłanie danych wpisu na serwer Ułatwienie korzystania ze strony blogu W ramach ułatwienia automatycznie wypełniaj pola formularzy Wielokrotnie wykonywane zadanie? Może by tak jakaś funkcja pomogła? 546 547 549 550 553 555 558 560 563 567 571 572 573 574 579 581 582 585 586 588 590 593 598 599 600 605 17 html head ... /head body ... /body /html youcube.html + blog title ... author ... entries entry ... /entry ... /entries /blog blog.xml = Skorowidz S 6. Funkcje Redukuj i używaj wielokrotnie Wiesz, co jest najważniejsze w klopsach? To, że przygotowujesz je raz, a potem możesz jeść tygodniami… Ratunku, niech mi ktoś pomoże! Gdyby w świecie JavaScriptu zaistniał jakiś ruch środowiskowy, to zapewne na jego czele stanęłyby funkcje. Funkcje pozwalają na pisanie bardziej efektywnego kodu i sprawiają, że łatwiej można go wielokrotnie używać. Funkcje są zorientowane na wykonywanie konkretnych zadań i znacząco ułatwiają organizację kodu. Wygląda to jak całkiem dobry życiorys! W praktyce niemal wszystkie skrypty, może za wyjątkiem tych najprostszych, mogą skorzystać na reorganizacji kodu i zastosowaniu funkcji. Choć trudno jest ocenić znaczenie i wpływ przeciętnej funkcji, to jednak należy zaznaczyć, że odgrywają one znaczącą rolę w staraniach, by skrypty były możliwie jak najbardziej przyjazne dla środowiska. to jest nowy rozdział (cid:23) 263 Podział dużych problemów Matka wszystkich problemów Skoro już o tym wspomnieliśmy, to warto zauważyć, że tworzenie skryptów na stronach WWW ma na celu rozwiązywanie problemów. Niezależnie od tego, jak duży i skomplikowany jest problem, jeśli zostanie on odpowiednio przemyślany, to zawsze znajdzie się rozwiązanie. No ale co z naprawdę wielkimi problemami? Pokój na świecie To jest naprawdę wielki problem! Cała sztuczka z rozwiązywaniem dużych problemów polega na podzieleniu ich na mniejsze, które będzie można łatwiej rozwiązać. A jeśli i te problemy są zbyt duże, to i je należy podzielić. Duży problem. Mniejszy problem. Pożywienie Schronienie Prawa obywatelskie Jeszcze mniejszy problem. Uprawa Dystrybucja Prawa do gruntów Budownictwo Wolność wypowiedzi Prawo do głosowania 264 Rozdział 6. Kontynuuj ten proces dalej i dalej, i dalej… Rozwiązuj duże problemy poprzez rozwiązywanie problemów mniejszych Kontynuując dzielenie problemu pokoju na świecie na coraz to mniejsze problemy, dojdziesz w końcu do problemu na tyle małego, że można go rozwiązać, wykorzystując JavaScript. Schronienie Budownictwo Dobry problem, który w sam raz nadaje się do rozwiązania w JavaScripcie. Materiały Narzędzia Klimatyzacja Spróbuj wymyślić JavaScriptowy odpowiednik problemu sterowania klimatyzacją, który wywoływałby skryptowy odpowiednik klimatyzatora, aby ten regulował temperaturę otoczenia. Najprostsze urządzenie do sterowania klimatyzacją, jakie można sobie wyobrazić, składałoby się wyłącznie z przycisku Ogrzewanie. Najprostszy z możliwych klimatyzatorów — naciśnij przycisk, a urządzenie zrobi, co trzeba. Zauważ, że urządzenie nie zdradza żadnej informacji, która mogłaby nam powiedzieć, w jaki sposób reguluje się temperaturę otoczenia. Wystarczy, że naciśniemy przycisk, a wszystko zostanie zrobione za nas. Ot — i tak oto problem klimatyzacji został rozwiązany! Funkcje Nie obchodzi nas, w jaki sposób urządzenie reguluje temperaturę — wystarczy, że będziemy wiedzieć, jak można je włączyć. jesteś tutaj (cid:23) 265 Funkcje — narzędzia do rozwiązywania niewielkich problemów Funkcje jako narzędzia do rozwiązywania problemów Przycisk Ogrzewanie służący do włączania klimatyzacji jest odpowiednikiem funkcji w języku JavaScript. Cały pomysł jest bardzo podobny do działania rzeczywistej klimatyzacji — ktoś żąda włączenia ogrzewania w domu, a funkcja mu to zapewnia. Szczegóły procesu ogrzewania są ukryte wewnątrz funkcji i nie mają najmniejszego znaczenia dla kodu, który ją wywołuje. Pod tym względem można wyobrazić sobie funkcję jako pewnego rodzaju „czarną skrzynkę” — informacje mogą do niej wpływać i wypływać, jednak to, co się dzieje wewnątrz, zależy wyłącznie od skrzynki i dlatego nie ma znaczenia dla kodu umieszczonego poza nią. Funkcje przekształcają duże problemy w mniejsze. Żądamy ogrzewania Temperatura się podnosi Stworzenie odpowiednika przycisku Ogrzewanie w kodzie JavaScript wymagałoby wywołania funkcji o nazwie heat()... Żądamy ogrzewania heat(); Temperatura się podnosi function heat() { // W jakiś sposób zaczynamy ogrzewać shovelCoal(); lightFire(); harnessSun(); } Każdy, kto chce włączyć ogrzewanie, musi wiedzieć, jak wywołać funkcję heat(). Samo ogrzewanie jest realizowane poprzez wywołanie trzech kolejnych funkcji. Jedyną osobą, która musi przejmować się faktycznym sposobem ogrzewania, jest twórca funkcji heat(). 266 Rozdział 6. Sposób, w jaki funkcja heat() wykonuje proces ogrzewania, nie ma kluczowego znaczenia. Najbardziej liczy się to, że funkcja ta stanowi niezależne rozwiązanie problemu ogrzewania. Jeśli jest Ci zimno i chcesz nieco podnieść temperaturę w domu, wystarczy wywołać tę funkcję. Szczegółowy sposób rozwiązania problemu ogrzewania pozostaje „słodką tajemnicą” funkcji. Funkcje Tworzenie funkcji w praktyce Kiedy podejmiesz decyzję napisania funkcji, automatycznie staniesz się autorem rozwiązania pewnego problemu. Stworzenie funkcji wymaga zastosowania spójnej składni, wiążącej jej nazwę z kodem, który dana funkcja ma wykonywać. W najprostszej wersji składnia funkcji ma następującą postać: Zaczynamy funkcję od słowa kluczowego function. To jest identyfikator zapisany według zasad notacji lowerCamelCase. function + Nazwa + () + { Kod umieszczony wewnątrz funkcji jest tak naprawdę częścią instrukcji złożonej, rozpoczynającej się tym nawiasem klamrowym. Ciało funkcji } Ciało funkcji to miejsce, w którym wykonywane są wszystkie operacje. Nawiasy wskazują, że mamy do czynienia z funkcją. Tu kończymy funkcję, umieszczając zamykający nawias klamrowy. Zapoznanie się z kodem umieszczonym wewnątrz funkcji heat() pozwala spojrzeć na składnię funkcji z nieco innej perspektywy: Tak naprawdę ogrzewanie jest realizowane wewnątrz funkcji. function heat() { // W jakiś sposób zaczynamy ogrzewać shovelCoal(); lightFire(); harnessSun(); } Ciało funkcji jest zapisane wewnątrz nawiasów klamrowych — czyli w rzeczywistości jest to doskonale nam już znana instrukcja złożona. WYTĘŻ UMYSŁ Gdzie we wcześniejszej części książki do rozwiązywania problemów wykorzystaliśmy funkcje? jesteś tutaj (cid:23) 267 Funkcje w aplikacji Mandango Funkcje, które już poznałeś Jeśli chcesz znaleźć doskonałe przykłady funkcji służących do rozwiązywania konkretnych problemów, wystarczy, że zajrzysz do aplikacji Mandango — wyszukiwarki miejsc dla prawdziwych macho (znajdziesz je na serwerze FTP wydawnictwa Helion, ftp://ftp.helion.pl/przyklady/hfjsc.zip). Przykładem tym jest funkcja służąca do inicjalizacji danych dotyczących dostępności miejsc. Wyszukiwanie miejsc dla macho Duży problem Inicjalizacja miejsc Wyszukiwanie miejsc Mniejsze problemy Podproblem polegający na inicjalizacji miejsc był na tyle mały, że udało się go nam rozwiązać i zaimplementować w postaci funkcji, a konkretnie rzecz biorąc: funkcji initSeats(): function initSeats() { // Inicjalizacja wyglądu wszystkich miejsc for (var i = 0; i seats.length; i++) { for (var j = 0; j seats[i].length; j++) { if (seats[i][j]) { // Określamy dostępne miejsce document.getElementById( seat + (i * seats[i].length + j)).src = seat_avail.png ; document.getElementById( seat + (i * seats[i].length + j)).alt = Miejsce dostępne ; } else { // Określamy zajęte (niedostępne) miejsce document.getElementById( seat + (i * seats[i].length + j)).src = seat_unavail.png ; document.getElementById( seat + (i * seats[i].length + j)).alt = Miejsce zajęte ; } } } } Funkcja initSeats() jest jednym z elementów aplikacji Mandango. Funkcja ta jest wywoływana dopiero w procedurze obsługi zdarzeń onload; a zatem zostanie ona wykonana dopiero po wczytaniu całej strony. Funkcja initSeats() nie jest jedynym narzędziem do rozwiązywania problemów wykorzystywanym w aplikacji Mandango. body onload= initSeats(); div style= margin-top:25px; text-align:center img id= seat0 src= alt= / ... img id= seat1 src= alt= / img id= seat35 src= alt= / br / input type= button id= findseats value= Szukaj miejsc onclick= findSeats(); / /div /body /html 268 Rozdział 6. P: Możesz jeszcze raz przypomnieć konwencje używane podczas określana nazw funkcji? O: Podczas określania nazw identyfikatorów w JavaScripcie używana jest konwencja lowerCamelCase, w myśl której pierwsze słowo identyfikatora jest zapisywane małą literą, a wszystkie pozostałe — wielką. A zatem funkcja służąca do oceniania filmów nosiłaby nazwę ocenFilm(), natomiast funkcja usuwająca z sali kinowej widza, który zapomniał wyłączyć telefonu komórkowego, mogłaby się nazywać: usunHalasliwegoWidza(). P: Czy funkcje zawsze służą do dzielenia dużych problemów na mniejsze? O: Niekoniecznie. Czasami przydatne może być także zastosowanie funkcji do dzielenia pracy nad kodem. Innymi słowy, może się zdarzyć, że jeden problem będzie rozwiązywany przez kilka współpracujących ze sobą funkcji. Nie ma niemądrych pytań W takim przypadku podział kodu na funkcje ma nam umożliwić organizację pracy i ułatwić tworzenie funkcji, z których każda będzie mieć jedno precyzyjnie określone przeznaczenie. Na podobnej zasadzie pracownicy są zatrudniani na stanowiskach o różnych nazwach, by każdy z nich mógł się skupić na rozwiązywaniu unikalnych i konkretnych problemów. Takie funkcje mogą, choć nie muszą, rozwiązywać konkretne problemy; niemniej na pewno poprawiają strukturę skryptów, gdyż pozwalają dzielić ich kod na części. P: A skąd wiadomo, kiedy i jaki fragment kodu należy zaimplementować jako funkcję? O: Niestety, nie ma żadnego magicznego sposobu, który pozwalałby określić, kiedy warto napisać fragment kodu jako funkcję. Można jednak wskazać pewne czynniki, które można potraktować jako sygnały i podpowiedzi dotyczące możliwości tworzenia funkcji. Jednym z nich jest sytuacja, w której pewien fragment kodu będzie się powtarzać. Powielanie kodu niemal nigdy nie Funkcje jest ani dobrym, ani zalecanym rozwiązaniem, gdyż zmusza nas do pielęgnacji i ewentualnej modyfikacji kodu w kilku miejscach skryptu. A zatem taki powtarzający się kod doskonale nadaje się do zaimplementowania w formie funkcji. Innym sygnałem, na jaki należy zwracać uwagę, są długie, trudne do zarządzania bloki kodu, które w prosty sposób można podzielić na kilka logicznych części. Taki kod to doskonała okazja do zastosowania „podziału pracy” — czyli podzielenia tego kodu na części i umieszczenia ich w odrębnych funkcjach. P: Czy nie wspominałeś o tym, że funkcje mogą akceptować argumenty i zwracać wartości? Czy o czymś zapomniałem? O: Nie. Bez wątpienia są funkcje, które wymagają przekazania danych i jednocześnie zwracają jakieś wyniki. Jak się okaże, właśnie taka będzie funkcja heat(), którą poznasz w dalszej części rozdziału. Nazwa funkcji ma bardzo duże znaczenie, gdyż może przekazywać informacje o jej przeznaczeniu. Spróbuj wymyślić nazwy dla opisanych poniżej funkcji, pamiętając przy tym, by w odpowiedni sposób je zapisać. Ćwiczenie Poproś o fotel przy przejściu Poproś o zwrot kosztów Wyrzuć popcorn Odbierz bilet. ............................................ Odbierz przyznane pieniądze. ............................................ Popcorn został rozsypany na innych widzów. ............................................ jesteś tutaj (cid:23) 269 Rozwiązanie ćwiczenia Ćwiczenie Rozwiązanie Poproś o fotel przy przejściu Nazwa funkcji ma bardzo duże znaczenie, gdyż może przekazywać informacje o jej przeznaczeniu. Spróbuj wymyślić nazwy dla opisanych poniżej funkcji, pamiętając przy tym, by w odpowiedni sposób je zapisać. Odbierz bilet. poprosOMiejscePrzyPrzejsciu() ................................................................ Poproś o zwrot kosztów Wyrzuć popcorn Odbierz przyznane pieniądze. poprosOZwrot() ................................................................. Popcorn został rozsypany na innych widzów. wyrzucPopcorn() ................................................................ Z powodzeniem można by wymyślić inne nazwy dla tych funkcji. W każdym razie są to przykłady sensownych nazw zapisanych zgodnie z założeniami notacji lowerCamelCase. Chyba się ugotuję, niech ktoś wyłączy ogrzewanie. A może to efekt lokalnego ocieplenia klimatu? Sss… ale milutko! Zbyt gorąco by cokolwiek zrobić W międzyczasie okazało się, że próby zapewnienia pokoju na świecie poprzez kontrolę temperatury otoczenia zaczynają przynosić więcej szkód niż pożytku. Wygląda na to, że przycisk Ogrzewanie działa aż nazbyt dobrze… choć może to jest problem z funkcją heat(), do której powinniśmy przekazywać więcej informacji? Niezależnie od przyczyny, coś z tym trzeba zrobić. 270 Rozdział 6. Lepsza klimatyzacja dzięki większej ilości danych Wróćmy zatem do naszej klimatyzacji… Urządzenie to nie wie, kiedy należy przerwać ogrzewanie, gdyż nie określiliśmy żadnej temperatury docelowej. A zatem nasza klimatyzacja nie ma wystarczającej ilości informacji, by efektywnie rozwiązać problem. Oznacza to, że kiedy ktoś naciśnie przycisk Ogrzewanie, klimatyzacja zacznie ogrzewać… i nigdy już nie przestanie! Funkcje Pokrętło regulacji temperatury pozwala użytkownikom określić temperaturę docelową. Poprawiony klimatyzator pozwala teraz na określenie temperatury docelowej, stanowiącej informację wejściową, dzięki której można usprawnić proces ogrzewania. Temperatura docelowa Żądamy ogrzewania Temperatura się podnosi Temperatura docelowa jest informacją wejściową przekazywaną do funkcji. heat(targetTemp); Ćwiczenie Napisaliśmy pierwszy wiersz kodu, by ułatwić Ci rozwiązanie ćwiczenia. Napisz kod poprawionej funkcji heat(), która pobiera temperaturę docelową i działa (czyli generuje ciepło) wyłącznie wtedy, gdy temperatura zmierzona w danej chwili jest mniejsza od docelowej. Podpowiedź: skorzystaj z hipotetycznej funkcji getTemp(), by określić, jaka jest temperatura w danej chwili. function heat(targetTemp) ................................................................................................................................................................. ................................................................................................................................................................. ................................................................................................................................................................. ................................................................................................................................................................. ................................................................................................................................................................. ................................................................................................................................................................. jesteś tutaj (cid:23) 271 Rozwiązanie ćwiczenia Ćwiczenie Rozwiązanie Temperatura docelowa jest przekazywana do funkcji jako argument jej wywołania. Obecnie funkcja generuje ciepło wyłącznie wtedy, gdy aktualna temperatura jest mniejsza od temperatury docelowej. Napisz kod poprawionej funkcji heat(), która pobiera temperaturę docelową i działa (czyli generuje ciepło) wyłącznie wtedy, gdy temperatura zmierzona w danej chwili jest mniejsza od docelowej. Podpowiedź: skorzystaj z hipotetycznej funkcji getTemp(), by określić, jaka jest temperatura w danej chwili. function heat(targetTemp) ................................................................................................................................................................. while (getTemp() targetTemp) { ................................................................................................................................................................. // W jakiś sposób zaczynamy ogrzewać ................................................................................................................................................................. Temperatura docelowa shovelCoal(); jest używana jako element ................................................................................................................................................................. warunku sprawdzanego w pętli while. lightFire(); ................................................................................................................................................................. harnessSun(); ................................................................................................................................................................. } ................................................................................................................................................................. } ................................................................................................................................................................. Przekazywanie informacji do funkcji Dane są przekazywane do funkcji przy użyciu tak zwanych argumentów. Przyjrzyj się jeszcze raz składni funkcji i zwróć szczególną uwagę na argumenty umieszczane pomiędzy nawiasami, za nazwą tworzonej funkcji: Wewnątrz nawiasów można umieścić jeden lub więcej argumentów. function + Nazwa + ( + Argumenty + ) + { Ciało funkcji } Wewnątrz ciała funkcji argumenty są używane tak, jak gdyby były zainicjowanymi zmiennymi lokalnymi. Nie ma żadnego limitu określającego maksymalną liczbę argumentów, jakie można przekazać do funkcji, jednak ze względów praktycznych warto dołożyć starań, by nie było ich więcej niż dwa lub trzy. Argumentem przekazywanym do funkcji może być niemal każda informacja: stała (Math.PI), zmienna (temp), jak również literał (23). 272 Rozdział 6. Argumenty funkcji jako dane Funkcje Kiedy korzystając z mechanizmu argumentów, przekazujemy do funkcji pewne dane, to wewnątrz tej funkcji stają się one zainicjowanymi zmiennymi lokalnymi. Przykładem może być funkcja heat(), do której przekazujemy argument określający temperaturę docelową: heat(23); Zadana temperatura docelowa jest przekazywana do funkcji jako literał liczbowy. Wewnątrz funkcji heat() do informacji o temperaturze docelowej odwołujemy się jak do zwyczajnej zainicjowanej zmiennej lokalnej o wartości 23. Wartość tę można wyświetlić, wywołując wewnątrz funkcji heat() informacyjne okienko dialogowe: Wewnątrz funkcji heat() argument wygląda jak każda inna zmienna lokalna. 2 3 function heat(targetTemp) { alert(targetTemp); } 2323 Kiedy wykonywanie funkcji się zakończy, zmienna targetTemp zostanie usunięta. targetTemp targetTemp Choć argumenty funkcji są bardzo podobne do zmiennych lokalnych, to jednak wszelkie modyfikacje argumentów wprowadzane wewnątrz funkcji nie mają żadnego wpływu na jakiekolwiek zmienne poza funkcją. Warto zapamiętać, że reguła ta nie odnosi się do obiektów przekazywanych do funkcji, jednak tymi zagadnieniami zajmiemy się bardziej szczegółowo w rozdziałach 9. i 10. var temp = 27; coolIt(temp); alert(temp); Pomimo że argument temp jest modyfikowany wewnątrz funkcji, to jednak zmienna przechowująca temperaturę poza funkcją pozostaje niezmieniona. Zmienna temp jest przekazywana do funkcji jako argument jej wywołania. Odejmujemy 1 od aktualnej temperatury. function coolIt(temperature) { temperature--; } jesteś tutaj (cid:23) 273 Usuwanie powtórzeń przy użyciu funkcji Funkcje eliminują powtarzający się kod Funkcji można z powodzeniem używać nie tylko do dzielenia dużych problemów na mniejsze, które będzie można łatwiej rozwiązać. Oprócz tego — dzięki możliwości uogólniania zadań — funkcje doskonale nadają się do eliminowania wielokrotnie powtarzającego się kodu. Choć niejednokrotnie powtarzający się kod nie jest dokładnie identyczny we wszystkich miejscach, to jednak często można go uogólnić i stworzyć jedną wersję, która następnie zostanie umieszczona w funkcji. Następnie można korzystać z tej funkcji, zamiast powielać fragment kodu. Poniżej przedstawiliśmy trzy różne fragmenty kodu, które wykonują podobne zadania. Fragmenty te z powodzeniem można uogólnić i zaimplementować w formie jednej ogólnej funkcji nadającej się do wielokrotnego zastosowania: Wyrażenie obliczające cenę biletu ze zniżką jest niepotrzebnie powtarzane. // Bilet na seans popołudniowy jest tańszy o 10 biletPopoludniowy = biletNormalny * (1 – 0.10); // Bilet dla seniorów jest tańszy o 15 biletSeniorski = biletNormalny * (1 – 0.15 ); // Bilet dla dzieci jest tańszy o 20 biletDzieciecy = biletNormalny * (1 – 0.20); Powyższe zadania polegają na obliczeniu ceny trzech różnych zniżkowych biletów do kina. Można je jednak uogólnić do jednego zadania, które będzie obliczać cenę biletu na podstawie dowolnej zniżki, określonej jako wartość procentowa. Funkcje potrafią także zwracać dane. function cenaZeZnizka(cena, znizkaProcentowa) { return (cena * (1 – (znizkaProcentowa / 100))); } Dysponując funkcją obliczającą ceny biletów ze zniżką, możemy zmodyfikować trzy przedstawione wcześniej zadania, poprawiając przy tym ich efektywność: // Bilet na seans popołudniowy jest tańszy o 10 biletPopoludniowy = cenaZeZnizka(biletNormalny, 10); // Bilet dla seniorów jest tańszy o 15 biletSeniorski = cenaZeZnizka(biletNormalny, 15); // Bilet dla dzieci jest tańszy o 20 biletDzieciecy = cenaZeZnizka(biletNormalny, 20); 274 Rozdział 6. BĄDŹ ekspertem do spraw wydajności Poniżej przedstawiliśmy kod funkcji findSeats() z aplikacji Mandango w całej jego okazałości. Korzystając ze swojej nowej wiedzy dotyczącej efektywności, zakreśl podobne fragmenty kodu, które można by w uogólnionej postaci zaimplementować jako funkcję. function findSeats() { // Jeśli jakieś miejsce już zostało wybrane, to ponownie inicjujemy // wszystkie miejsca, by anulować wcześniejszy wybór. if (selSeat = 0) { selSeat = -1; initSeats(); } // Przeglądamy wszystkie miejsca, poszukując dostępnych var i = 0, finished = false; while (i seats.length !finished) { for (var j = 0; j seats[i].length; j++) { // Sprawdzamy, czy aktualnie analizowane miejsce i dwa następne są dostępne if (seats[i][j] seats[i][j + 1] seats[i][j + 2]) { // Ustawiamy wybór i aktualizujemy wygląd miejsca selSeat = i * seats[i].length + j; document.getElementById( seat” + (i * seats[i].length + j)).src = seat_select.png”; document.getElementById( seat” + (i * seats[i].length + j)).alt = Twoje miejsce”; document.getElementById( seat” + (i * seats[i].length + j + 1)).src = seat_select.png”; document.getElementById( seat” + (i * seats[i].length + j + 1)).alt = Twoje miejsce”; document.getElementById( seat” + (i * seats[i].length + j + 2)).src = seat_select.png”; document.getElementById( seat” + (i * seats[i].length + j + 2)).alt = Twoje miejsce”; // Prosimy użytkownika o zaakceptowanie wyboru miejsca var accept = confirm( Miejsca od + (j + 1) + do + (j + 3) + w rzędzie + (i + 1) + są wolne. Wybrać je?”); if (accept) { // Użytkownik zaakceptował miejsce — kończymy (wychodzimy z wewnętrznej pętli) finished = true; break; } else { // Użytkownik odrzucił wybór, zatem anulujemy wybór i szukamy dalej selSeat = -1; document.getElementById( seat” + (i * seats[i].length + j)).src = seat_avail.png”; document.getElementById( seat” + (i * seats[i].length + j)).alt = Miejsce dostępne”; document.getElementById( seat” + (i * seats[i].length + j + 1)).src = seat_avail.png”; document.getElementById( seat” + (i * seats[i].length + j + 1)).alt = Miejsce dostępne”; document.getElementById( seat” + (i * seats[i].length + j + 2)).src = seat_avail.png”; document.getElementById(“seat” + (i * seats[i].length + j + 2)).alt = “Miejsce dostępne”; } } } // Inkrementujemy licznik zewnętrznej pętli i++; } } Funkcje jesteś tutaj (cid:23) 275 Rozwiązanie ćwiczenia BĄDŹ ekspertem do spraw wydajności Poniżej przedstawiliśmy kod funkcji findSeats() z aplikacji Mandango w całej jego okazałości. Korzystając ze swojej nowej wiedzy dotyczącej efektywności, zakreśl podobne fragmenty kodu, które można by w uogólnionej postaci zaimplementować jako funkcję. function findSeats() { // Jeśli jakieś miejsce już zostało wybrane, to ponownie inicjujemy // wszystkie miejsca, by anulować wcześniejszy wybór. if (selSeat = 0) { selSeat = -1; initSeats(); } // Przeglądamy wszystkie miejsca, poszukując dostępnych var i = 0, finished = false; while (i seats.length !finished) { for (var j = 0; j seats[i].length; j++) { // Sprawdzamy, czy aktualnie analizowane miejsce i dwa następne są dostępne if (seats[i][j] seats[i][j + 1] seats[i][j + 2]) { // Ustawiamy wybór i aktualizujemy wygląd miejsca selSeat = i * seats[i].length + j; document.getElementById( seat” + (i * seats[i].length + j)).src = seat_select.png”; document.getElementById( seat” + (i * seats[i].length + j)).alt = Twoje miejsce”; document.getElementById( seat” + (i * seats[i].length + j + 1)).src = seat_select.png”; document.getElementById( seat” + (i * seats[i].length + j + 1)).alt = Twoje miejsce”; document.getElementById( seat” + (i * seats[i].length + j + 2)).src = seat_select.png”; document.getElementById( seat” + (i * seats[i].length + j + 2)).alt = Twoje miejsce”; // Prosimy użytkownika o zaakceptowanie wyboru miejsca var accept = confirm( Miejsca od + (j + 1) + do + (j + 3) + w rzędzie + (i + 1) + są wolne. Wybrać je?”); if (accept) { // Użytkownik zaakceptował miejsce — kończymy (wychodzimy z wewnętrznej pętli) finished = true; break; } else { // Użytkownik odrzucił wybór, zatem anulujemy wybór i szukamy dalej selSeat = -1; document.getElementById( seat” + (i * seats[i].length + j)).src = seat_avail.png”; document.getElementById( seat” + (i * seats[i].length + j)).alt = Miejsce dostępne”; document.getElementById( seat” + (i * seats[i].length + j + 1)).src = seat_avail.png”; document.getElementById( seat” + (i * seats[i].length + j + 1)).alt = Miejsce dostępne”; document.getElementById( seat” + (i * seats[i].length + j + 2)).src = seat_avail.png”; document.getElementById(“seat” + (i * seats[i].length + j + 2)).alt = “Miejsce dostępne”; } } } Ponieważ każdy z tych sześciu fragmentów kodu wykonuje dokładnie to samo zadanie, zatem można je zamienić w jedną funkcję. // Inkrementujemy licznik zewnętrznej pętli i++; } } 276 Rozdział 6. Właściwość length wciąż jest używana do określania liczby elementów w tablicy wewnętrznej. Te fragmenty kodu powtarzają się. Możemy w nich wyróżnić pewne atrybuty… Funkcje Wiem, ale pozwól, że oddzwonię za chwilę… mam kogoś na drugiej linii. Tworzenie funkcji określającej status miejsc Teraz, gdy autorzy aplikacji Mandango zobaczyli, co oznacza poprawianie efektywności, aż palą się do dodawania nowych funkcji, dzięki którym ich kod mógłby być jeszcze bardziej wydajny (kody wszystkich przykładów prezentowanych w książce znajdziesz na serwerze FTP wydawnictwa Helion, ftp://ftp.helion.pl/przyklady/hfjsc.zip). Jednak, by móc napisać funkcję setSeat(), Szymek i Jasiek muszą najpierw określić, jakie argumenty będą konieczne do jej działania. Argumenty te można podać, analizując powtarzające się fragmenty kodu i wskazując dane, które w każdym z nich mają inne wartości. Analiza powtarzających się fragmentów funkcji findSeats(), pozwala wyróżnić następujące argumenty: Numer miejsca Numer miejsca, którego status będzie ustawiany. Nie jest to jednak indeks tabeli, lecz numer liczony od lewej do prawej i z góry w dół, zaczynając od 0. Chłopie, funkcje rządzą! Musimy ich mieć jak najwięcej. Atrybuty funkcji findSeats() zostały wskazane poprzez analizę powtarzającego się kodu, który niebawem umieścimy w nowej funkcji. Status Status miejsca. Może on przyjmować wartości: dostępne, zajęte, wybrane. Na jego podstawie określany jest wyświetlany na stronie obrazek miejsca. Opis Opis aktualnego statusu miejsca. Może przyjmować wartości: Miejsce dostępne, Miejsce zajęte oraz Twoje miejsce. Służy do określania wartości atrybutu alt elementu obrazka reprezentującego dane miejsce. Zaostrz ołówek Napisz kod funkcji setSeat() dla aplikacji Mandango. ................................................................................................................................................ ................................................................................................................................................ ................................................................................................................................................ ................................................................................................................................................ jesteś tutaj (cid:23) 277 Wielokrotne stosowanie kodu Zaostrz ołówek Konkretne dane zastosowane w oryginalnym kodzie zostały teraz zastąpione ogólnymi argumentami. Napisz kod funkcji setSeat() dla aplikacji Mandango. Poszczególne argumenty zostały od siebie oddzielone przecinkami. function setSeat(seatNum, status, description) { ................................................................................................................................................ document.getElementById( seat + seatNum).src = seat_ + status + .png ; ................................................................................................................................................ document.getElementById( seat + seatNum).alt = description ; ................................................................................................................................................ } ................................................................................................................................................ Bardziej elegancki i przejrzysty kod dzięki zastosowaniu funkcji Umieszczenie powtarzającego się kodu w funkcji setSeat() w znaczący sposób uprościło kod funkcji findSeats(). Obecnie w kodzie funkcji findSeats() zostało umieszczonych aż sześć wywołań funkcji setSeat(), co stanowi znaczącą poprawę, jeśli chodzi o powtarzanie i wielokrotne stosowanie kodu. Numer miejsca, status oraz opis są przekazywane w każdym wywołaniu funkcji setSeat(). function findSeats() { ... // Przeglądamy wszystkie miejsca, poszukując dostępnych var i = 0, finished = false; while (i seats.length !finished) { for (var j = 0; j seats[i].length; j++) { // Sprawdzamy, czy aktualnie analizowane miejsce i dwa następne są dostępne if (seats[i][j] seats[i][j + 1] seats[i][j + 2]) { // Ustawiamy wybór i aktualizujemy wygląd miejsca selSeat = i * seats[i].length + j; setSeat(i * seats[i].length + j, select , Twoje miejsce ); setSeat(i * seats[i].length + j + 1, select , Twoje miejsce ); setSeat(i * seats[i].length + j + 2, select , Twoje miejsce ); // Prosimy użytkownika o zaakceptowanie wyboru miejsca var accept = confirm( Miejsca od + (j + 1) + do + (j + 3) + w rzędzie + (i + 1) + są wolne. Wybrać je? ); if (accept) { // Użytkownik zaakceptował miejsce — kończymy (wychodzimy z wewnętrznej pętli) finished = true; break; } else { // Użytkownik odrzucił wybór, zatem anulujemy wybór i szukamy dalej selSeat = -1; setSeat(i * seats[i].length + j, avail , Miejsce dostępne ); setSeat(i * seats[i].length + j + 1, avail , Miejsce dostępne ); setSeat(i * seats[i].length + j + 2, avail , Miejsce dostępne ); } } } // Inkrementujemy licznik zewnętrznej pętli i++; } } Nasza nowa funkcja setSeat() jest wywoływana w sześciu miejscach. 278 Rozdział 6. Funkcja setSeat() jeszcze bardziej poprawia kod aplikacji Mandango Jednak nie tylko funkcja findSeats() skorzystała na zaimplementowaniu naszej nowej funkcji setSeat(). Poprawiona została także efektywność działania funkcji initSeats(), gdyż także w niej znajdował się kod określający status miejsc. Funkcje function initSeats() { // Inicjalizacja wyglądu wszystkich miejsc for (var i = 0; i seats.length; i++) { for (var j = 0; j seats[i].length; j++) { if (seats[i][j]) { // Określamy dostępne miejsce document.getElementById( seat + (i * seats[i].length + j)).src = seat_avail.png ; document.getElementById( seat + (i * seats[i].length + j)).alt = Miejsce dostępne ; } else { // Określamy zajęte (niedostępne) miejsce document.getElementById( seat + (i * seats[i].length + j)).src = seat_unavail.png ; document.getElementById( seat + (i * seats[i].length + j)).alt = Miejsce zajęte ; } } } } Dwa całkiem złożone wiersze kodu zostały zastąpione jednym stosunkowo prostym wywołaniem funkcji. Poprzez uogólnienie operacji określenia statusu miejsca funkcja setSeat() doskonale się spisuje w bardzo różnych sytuacjach function initSeats() { // Inicjalizacja wyglądu wszystkich miejsc for (var i = 0; i seats.length; i++) { for (var j = 0; j seats[i].length; j++) { if (seats[i][j]) { // Określamy dostępne miejsce setSeat(i * seats[i].length + j, avail , Miejsce dostępne ); } else { // Określamy zajęte (niedostępne) miejsce setSeat(i * seats[i].length + j, unavail , Miejsce zajęte ); } } } } Jak zatem widać, stosunkowo prosta funkcja składająca się z dwóch wierszy kodu jest obecnie wywoływana aż w ośmiu miejscach kodu aplikacji Mandango. Nie tylko upraszcza to kod skryptu, lecz także znacznie ułatwia jego utrzymanie, gdyż gdybyś w przyszłości musiał zmodyfikować sposób zmiany statusu miejsc, wystarczy zmienić go raz — w kodzie funkcji setSeat() — a nie w ośmiu różnych miejscach całego skryptu. Żaden programista o
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Head First JavaScript. Edycja polska
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: