Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00238 015884 17222454 na godz. na dobę w sumie
Programowanie w JavaScript. Rusz głową! - książka
Programowanie w JavaScript. Rusz głową! - książka
Autor: , Liczba stron: 664
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-9880-6 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> javascript - programowanie
Porównaj ceny (książka, ebook (-25%), audiobook).

Jeżeli chcesz stworzyć atrakcyjną aplikację internetową lub stronę WWW, to poza znajomością języka HTML powinieneś również umieć korzystać z JavaScriptu. Język ten jeszcze całkiem niedawno wzbudzał wiele negatywnych emocji — ale te czasy odeszły w niepamięć! Bez jego pomocy współczesne strony WWW nie byłyby takie funkcjonalne!

Jeżeli chcesz poznać możliwości JavaScriptu oraz w pełni wykorzystać jego potencjał, trafiłeś na doskonałą książkę. Należy ona do cenionej serii „Rusz głową” i opisuje wszystkie aspekty programowania w tym języku. Sięgnij po nią i poznaj język JavaScript od podstaw. Każda kolejna strona to spora dawka wiedzy podanej w przystępny sposób. Pomoże Ci poznać składnię języka, jego podstawowe elementy i konstrukcje. W momencie, kiedy opanujesz podstawy, przejdziesz do bardziej zaawansowanych tematów — programowania obiektowego, manipulowania drzewem DOM, obsługi zdarzeń oraz korzystania z funkcji anonimowych i domknięć. Książka ta jest doskonałą lekturą dla wszystkich osób chcących biegle władać językiem JavaScript!


Dzięki tej książce:

Nauka języka JavaScript jeszcze nigdy nie była tak przyjemna!

 

„Doskonałe wprowadzenie do programowania, połączone z zaawansowanymi zagadnieniami, takimi jak tworzenie obiektów, dziedziczenie i domknięcia, pozwalające czytelnikom przejść od samych podstaw, aż do najbardziej interesujących pojęć nowoczesnego programowania”.

Peter Casey, profesor, Central Oregon Community College

„Ta książka przenosi Cię za kulisy języka JavaScript i zapewnia dogłębne zrozumienie zasad działania tego wyjątkowego języka programowania”.

Chris Fuselier, konsultant techniczny

„Szkoda, że nie miałam książki Programowanie w JavaScript. Rusz głową! kiedy zaczynałem”.

Daniel Konopacki; projektant oprogramowania kadrowego; The Wald Disney Company





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

Darmowy fragment publikacji:

Tytuł oryginału: Head First JavaScript Programming Tłumaczenie: Piotr Rajca ISBN: 978-83-246-9880-6 © 2015 Helion S.A. Authorized Polish translation of the English edition of Head First JavaScript Programming 9781449340131 © 2014 Eric Freeman and Elisabeth Robson. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/prjsrg Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis treści (skrócony) Wprowadzenie Interakcja ze stronami WWW: Poznajemy DOM 1. Szybki skok na głębokie wody JavaScriptu: Czas się zamoczyć 2. Pisanie prawdziwego kodu: Idziemy dalej 3. Przedstawienie funkcji: Stawiamy na funkcjonalność 4. Porządkowanie naszych danych: Tablice 5. Zrozumieć obiekty: Wycieczka do Obiektowa 6. 7. Typy, równość, konwersje i cały ten jazz: Poważne typy 8. Łączenie wszystkiego w całość: Tworzenie aplikacji 9. Programowanie asynchroniczne: Obsługa zdarzeń 10. Funkcje pierwszej klasy: Wyzwolone funkcje 11. Funkcje anonimowe, zasięg i domknięcia: Poważne funkcje 12. Zaawansowane sposoby konstruowania obiektów: Tworzenie obiektów 13. Stosowanie prototypów: Obiekty ekstramocne A Dziesięć najważniejszych zagadnień (których nie opisaliśmy): Pozostałości Spis treści 25 39 81 115 159 205 259 293 343 407 453 499 543 583 643 Spis treści (pełny) W Wprowadzenie Twój mózg koncentruje się na języku JavaScript. W tym miejscu Ty usiłujesz się czegoś nauczyć, a Twój mózg robi Ci przysługę i stara się, by wszystkie poznane informacje zostały zapomniane. Twój mózg myśli sobie: „Lepiej zostawić miejsce na naprawdę ważne informacje, takie jak dzikie zwierzęta, których należy unikać, albo czy jeżdżenie nago na snowboardzie jest dobrym pomysłem”. W jaki sposób możesz przekonać swój mózg, by uznał, że Twoje życie zależy od znajomości JavaScriptu? Dla kogo jest ta książka? Wiemy, co myślisz Wyobrażamy sobie, że czytelnik tej książki jest uczniem Metapoznanie — myślenie o myśleniu To, co MY zrobiliśmy To, co TY możesz zrobić, aby zmusić swój mózg do posłuszeństwa Przeczytaj to Recenzenci techniczni Podziękowania* 26 27 28 29 30 31 32 35 36 9 Kup książkęPoleć książkę Spis treści 1 Szybki skok na głębokie wody JavaScriptu Czas się zamoczyć JavaScript to dane Ci supermoce. To prawdziwy język programowania internetu, który pozwala dodawać do stron WWW zachowania. Możesz zapomnieć o suchych, nudnych i statycznych stronach — z pomocą języka JavaScript będziesz w stanie porozumieć się ze swoimi użytkownikami, pobierać z internetu dane do wyświetlania na swoich stronach, rysować grafikę bezpośrednio na stronach i robić wiele innych, świetnych rzeczy. Co więcej, znając JavaScript, będziesz także mógł zapewniać swoim użytkownikom całkowicie nowe możliwości. HTML CSS przeglądarka JS Sposób działania języka JavaScript Jak należy pisać kod JavaScript? Jak umieszczać kod JavaScript na stronie? Dziecinko, JavaScript przebył długą drogę… Jak tworzyć instrukcje? Zmienne i wartości Odsuń się od tej klawiatury! Wyrazić się Wykonywanie operacji więcej niż jeden raz Jak działa pętla while? Podejmowanie decyzji w języku JavaScript A kiedy trzeba podejmować WIELE decyzji… Wyciągnij rękę i nawiąż kontakt z użytkownikami Poznajemy bliżej funkcję console.log Otwieranie konsoli Piszemy poważną aplikację JavaScript Jak mogę dodać kod do strony? (Niech policzę wszystkie sposoby) Będziemy musieli was rozdzielić 40 41 42 44 48 49 50 53 55 56 60 61 63 65 66 67 70 71 ku r i e r sieciowski Jak uniknąć tych żenujących błędów w nazwach? Masz bardzo dużo swobody w dobieraniu nazw zmiennych, redakcja zebrała zatem porady kilku sieciowickich ekspertów, by ułatwić Ci dobieranie nazw. Wybieraj nazwy, które coś znaczą. Takie nazwy zmiennych jak _m, $, r lub foo zapewne znaczą coś dla Ciebie, jednak społeczność Sieciowic patrzy na nie raczej niechętnie. Nie tylko dlatego, że z czasem zapewne zapomnisz, co znaczą, lecz także dlatego, że sam kod będzie czytelniejszy, kiedy użyjesz nazw, takich jak currentPreasure lub passedExam. Tworząc nazwy składające się z kilku słów, używaj zapisu camel case. Wcześniej czy później będziesz musiał utworzyć zmienną reprezentującą np. dwugłowego smoka ziejącego ogniem. Jak? Wystarczy użyć zapisu camel case, w którym pierwsze litery poszczególnych słów (z wyjątkiem pierwszego) zapisywane są wielkimi literami; oto przykład twoHeadedDragonWithFire. Takie nazwy łatwo się tworzy, potrafią się nimi posługiwać wszyscy w Sieciowicach, a poza tym zapewniają dużą elastyczność w tworzeniu dowolnych nazw spełniających Twoje potrzeby. Istnieją także inne sposoby pisania nazw zmiennych, ale ten jest najczęściej używany (nawet w innych językach). Nazw zaczynających się od _ oraz $ używaj wyłącznie wtedy, kiedy masz naprawdę poważny powód. Nazwy zmiennych zaczynające się od znaku $ są zazwyczaj zarezerwowane dla bibliotek JavaScript i choć niektórzy autorzy używają znaku _ zgodnie z różnymi konwencjami, jednak zalecamy, by raczej nie używać żadnego z tych znaków; chyba że masz naprawdę ważne powody (będziesz wiedział, kiedy). Zachowaj bezpieczeństwo. Wybierając nazwy dla zmiennych, zachowaj bezpieczeństwo; kilka porad z tym związanych podamy dalej w książce, jednak na razie pamiętaj, by nazwy były zrozumiałe, unikaj słów kluczowych i zawsze na początku deklaracji umieszczaj słowo var. 10 Kup książkęPoleć książkę Spis treści 2 Pisanie prawdziwego kodu Idziemy dalej Już znasz zmienne, typy, wyrażenia…, możesz zatem pójść krok dalej. Chodzi o to, że już trochę poznałeś język JavaScript. Wiesz na tyle dużo, by napisać jakiś prawdziwy kod. Kod, który robi coś interesującego, którego ktoś chciałby używać. Jednak wciąż brakuje Ci praktycznego doświadczenia w pisaniu kodu. Właśnie mamy zamiar temu zaradzić, tu i teraz! A w jaki sposób? Skacząc na główkę na głęboką wodę i pisząc prostą grę, w całości w języku JavaScript. Cel jest bardzo ambitny, jednak będziemy go realizować krok po kroku. Chodź, zaczynamy! Jeśli zechcesz przy okazji uruchomić kolejny prosty startup, nie będziemy Ci przeszkadzać — kod jest Twój. Start Przygotowanie gry Pobranie sprawdzanego pola pudło Sprawdzenie pola trafienie Zaznaczenie okrętu jako trafionego zatopienie Zaznaczenie okrętu jako zatopionego Wyświetlenie wyniku/rankingu użytkownika Koniec gry No i proszę. Prawdziwy schemat blokowy. Napiszmy grę w okręty Pierwsza próba… Punkt pierwszy: projekt wysokiego poziomu Analiza pseudokodu A… zanim przejdziemy dalej, nie zapomnij o kodzie HTML Pisanie kodu prostej wersji gry w okręty A teraz zajmijmy się logiką gry Krok pierwszy: przygotowanie pętli i pobranie danych Jak działa funkcja prompt? Sprawdzanie komórki wskazanej przez użytkownika Czy użytkownikowi udało się trafić? Dodanie kodu wykrywającego trafienia Prezentacja informacji o zakończonej grze To koniec implementacji logiki Chwilka na zapewnianie jakości Czy możemy pogadać o rozwlekłości Twojego kodu? Kończymy prostą wersję gry w okręty Jak przypisywać wartości losowe? Najlepszy na świecie przepis na generowanie liczb losowych Wróćmy do zapewniania jakości Gratulujemy pierwszego prawdziwego programu w języku JavaScript i mamy dwa słowa o wielokrotnym używaniu kodu 82 82 83 85 87 88 89 90 91 92 94 95 96 98 99 103 104 105 105 107 109 11 Kup książkęPoleć książkę Spis treści 3 Przedstawienie funkcji Stawiamy na funkcjonalność Przygotuj się na użycie pierwszej ze swoich supermocy. Zdobyłeś już nieco umiejętności programistycznych; teraz nadszedł czas, aby rozwinąć je jeszcze bardziej przy użyciu funkcji. Funkcje zapewniają możliwość pisania kodu, który można stosować we wszelkich możliwych okolicznościach, kodu używanego wielokrotnie, którym można znacznie łatwiej zarządzać i w końcu który można wyodrębnić, nadać mu łatwą do zapamiętania nazwę, zapomnieć o całej jego złożoności i zająć się innymi ważnymi problemami. Przekonasz się, że funkcje to nie tylko droga, która zmieni Cię z autora skryptów w programistę. Są one kluczowym czynnikiem określającym styl programowania w języku JavaScript. W tym rozdziale zaczniemy od podstaw: poznasz mechanikę funkcji i tajniki ich działania, a dalej w tej książce będziesz stopniowo powiększać swoją wiedzę i umiejętności ich stosowania. A zatem, zacznij budować solidne podstawy znajomości JavaScriptu i zrób to już teraz. Co z tym kodem było nie tak? Swoją drogą, czy wspominaliśmy już o FUNKCJACH? No dobrze, ale jak to właściwie działa? Co można przekazywać do funkcji? JavaScript przekazuje przez wartość Zakręcone funkcje Funkcje mogą także coś zwracać Śledzenie wykonania funkcji z instrukcją return Zmienne globalne i lokalne Poznawanie zasięgu zmiennych lokalnych i globalnych Krótkie życie zmiennych Nie zapominaj o deklarowaniu zmiennych 117 119 120 125 128 130 131 132 135 137 138 139 12 Kup książkęPoleć książkę 4 Porządkowanie naszych danych Tablice 0 1 2 3 4 5 6 7 8 9 60 50 60 58 54 54 58 50 52 54 JavaScript to nie tylko liczby, łańcuchy znaków i wartości logiczne. Dotychczas pisałeś jedynie kod JavaScript, w którym były używane wartości typów prostych — proste łańcuchy znaków, liczby i wartości logiczne, takie jak „Burek”, 23 oraz true. Korzystając z takich wartości, można zrobić naprawdę dużo, jednak w którymś momencie będziesz musiał zacząć posługiwać się znacznie większą ilością danych. Przykładowo mogą to być wszystkie produkty umieszczone w koszyku zakupowym albo utwory na liście odtwarzania, albo gwiazdozbiory i współrzędne poszczególnych gwiazd, albo cały katalog produktów. Jednak do tego potrzebujesz czegoś bardziej… sexy. W języku JavaScript preferowanym typem danych dla takich uporządkowanych zbiorów informacji jest tablica, a w tym rozdziale dokładnie przeanalizujemy, jak umieszczać dane w tablicach, przekazywać tablice oraz jak na nich operować. Dalej w książce omówimy także kilka innych sposobów strukturyzacji danych, jednak zaczniemy od tablic. Czy możesz pomóc firmie BańkoCorp? Jak reprezentować wiele wartości w JavaScripcie? Jak działają tablice? A w ogóle jak duża jest tablica? Korpo-zdanio-budowator W międzyczasie w firmie BańkoCorp… Jak pobrać wszystkie elementy tablicy? Chwila, istnieje lepszy sposób iteracji po tablicy Czy możemy porozmawiać o rozwlekłości Twojego kodu? Poprawienie pętli for przy użyciu operatora postinkrementacji Szybka jazda próbna Tworzenie pustej tablicy (i dodawanie do niej danych) Zwycięzcami są… Krótka inspekcja kodu… Piszemy funkcję printAndGetHighScore Refaktoryzacja kodu z użyciem funkcji printAndGetHighScore Zastosowanie zmian… 160 161 162 164 166 169 172 174 180 181 181 185 189 191 192 193 195 13 Spis treściKup książkęPoleć książkę 5 Zrozumieć obiekty Wycieczka do Obiektowa Do tej pory w tworzonym kodzie używałeś jedynie danych typów prostych oraz tablic. Dodatkowo podchodziłeś do programowania w sposób proceduralny — korzystałeś z prostych instrukcji, instrukcji warunkowych oraz pętli, ewentualnie umieszczałeś je w funkcjach — to właściwie nie jest programowanie obiektowe. Prawdę powiedziawszy, to w ogóle nie jest programowanie obiektowe! Tu i tam, nawet o tym nie wiedząc, użyłeś — co prawda — kilku obiektów, jednak na razie jeszcze nie napisałeś żadnego własnego obiektu. Nadszedł najwyższy czas, żeby zostawić to stare i nudne proceduralne miasteczko i zacząć tworzenie własnych obiektów. W tym rozdziale dowiesz się, dlaczego stosowanie obiektów sprawi, że Twoje życie stanie się znacznie lepsze — przynajmniej pod względem programistycznym (niestety, w jednej książce nie możemy poprawić Twojej znajomości mody i jednocześnie nauczyć programowania w języku JavaScript). I jeszcze jedno ostrzeżenie: kiedy już poznasz obiekty, nigdy nie będziesz chciał ich porzucić. Wyślij nam pocztówkę, kiedy już dojedziesz do krainy obiektów. Czy ktoś powiedział „obiekty”? Myśląc o właściwościach… W jaki sposób tworzy się obiekty? Czym w ogóle jest programowanie obiektowe? Jak działają właściwości? W jaki sposób zmienna przechowuje obiekt? Ciekawe umysły chciałyby to wiedzieć… Porównanie danych typów prostych i obiektów Jeszcze inne operacje z wykorzystaniem obiektów… Analiza działania wstępnej selekcji Porozmawiajmy nieco więcej o przekazywaniu obiektów do funkcji Zachowuj się! Jak dodawać zachowania do obiektów? Poprawianie metody drive Dlaczego metoda drive nic nie wie o właściwości started? Jak działa this? Jak zachowanie wpływa na stan? Dodajemy trochę paliwa A teraz niech stan będzie mieć wpływ na zachowanie Gratulujemy utworzenia pierwszych obiektów! Wiesz co? Obiekty są wszędzie dookoła Ciebie (i ułatwiają Ci życie) 206 207 209 212 213 218 219 220 222 224 230 231 234 236 242 243 245 246 14 Spis treściKup książkęPoleć książkę Spis treści 6 Interakcja ze stronami WWW Poznajemy DOM Przebyłeś już długą drogę, poznając JavaScript. Powoli z żółtodzioba zmieniłeś się w twórcę prostych skryptów, a potem w końcu w programistę. Jednak wciąż Ci czegoś brakuje. Abyś mógł naprawdę wykorzystać całą swoją znajomość języka JavaScript, musisz dowiedzieć się, jak prowadzić interakcję ze stronami WWW, w których umieszczasz swoje skrypty. Tylko to pozwoli Ci tworzyć strony, które są dynamiczne, które reagują, odpowiadają i aktualizują swoją zawartość już po jej wczytaniu przez przeglądarkę. W jaki sposób można prowadzić interakcję ze stroną WWW? Służy do tego DOM, nazywany także obiektowym modelem dokumentu. W tym rozdziale opiszemy go szczegółowo i wyjaśnimy, jak można z niego korzystać i jak go używać wraz z językiem JavaScript, by nauczyć nasze strony wykonywania wielu nowych sztuczek. To ja: przeglądarka! Właśnie wyświetlam stronę i tworzę jej DOM. W poprzednim rozdziale miałeś wykonać niewielką misję — misję złamania kodu Co robi ten kod? Jak naprawdę wygląda interakcja JavaScriptu ze stroną WWW? Jak wypiec swój własny DOM? Pierwszy smak DOM Pobieranie elementu przy użyciu metody getElementById Co pobieramy z DOM? Dostęp do kodu HTML w elemencie Co się dzieje, kiedy zmieniamy DOM? Jazda próbna wokół planet Nawet nie myśl o uruchamianiu mojego kodu, zanim strona 279 nie zostanie w całości wczytana 280 Ty mówisz: „przeglądarka”, ja mówię: „wywołanie zwrotne” Jak ustawiać atrybuty przy użyciu metody setAttribute? 285 Więcej zabawy z atrybutami (wartości atrybutów można także POBIERAĆ) 286 286 Nie zapominaj, że także metoda getElementById może zwracać null Tymczasem w systemie słonecznym… 287 260 261 263 264 265 270 271 272 274 277 document html body head p id =”greenplanet” p id =”redplanet” p id =”blueplanet” Wszystko jest w porządku Nie ma tu nic ciekawego Wszystkie systemy sprawne 15 Kup książkęPoleć książkę Spis treści 7 Typy, równość, konwersje i cały ten jazz Poważne typy Nadszedł czas, by poważnie przyjrzeć się typom. Jedną ze wspaniałych cech JavaScriptu jest to, że można w nim zrobić całkiem dużo bez jego szczegółowej znajomości. Aby jednak perfekcyjnie opanować język, dostać awans i zacząć robić to, co naprawdę chcesz robić w życiu, musisz się zaprzyjaźnić z typami. Czy pamiętasz, co już dawno, na samym początku książki powiedzieliśmy na temat JavaScriptu? Że nie może się poszczycić rozpuszczoną, popularną, akademicką definicją? No cóż… To prawda, jednak życie akademickie nie zatrzymało ani Steve’a Jobsa ani Billa Gatesa, nie zatrzymało także języka JavaScript. Oznacza to jednak, że JavaScript nie ma… hm… doskonale przemyślanego systemu typów i znajdziemy w nim sporo dziwactw. Nie obawiaj się jednak — w tym rozdziale dokładnie wszystko wyjaśnimy, dzięki czemu już niebawem nauczysz się unikać tych wszystkich zawstydzających problemów z typami. Gdzieś tam jest ukryta prawda… Uważaj, możesz natknąć się na undefined, kiedy będziesz się tego najmniej spodziewać… Jak używać null? Stosowanie wartości NaN Sprawy stają się jeszcze dziwniejsze Musimy coś wyznać Zrozumienie operatora równości (pseudonim: ==) Jak wykonywana jest konwersja operandów operatora równości (brzmi groźniej, niż jest w rzeczywistości)? Jak ściśle podejść do zagadnienia równości? Jeszcze więcej konwersji typów… Jak określić, czy dwa obiekty są równe? Gdzieś tam leży prawda… JavaScript uwzględnia fałsz Sekretne życie łańcuchów znaków Dlaczego łańcuch może wyglądać jak dana typu prostego oraz jak obiekt? Pięciominutowa wycieczka po metodach (i właściwościach) łańcuchów znaków Wojna o fotel 294 296 299 301 301 303 304 305 308 314 317 319 320 322 323 325 329 16 Kup książkęPoleć książkę Spis treści 8 Łączenie wszystkiego w całość Tworzenie aplikacji Włóż to do swojego przybornika z narzędziami, czyli do skrzynki, w której umieszczasz wszystkie swoje nowe umiejętności programistyczne, wiedzę dotyczącą DOM, a nawet HTML i CSS. W tym rozdziale wykorzystasz wszystkie te umiejętności, by utworzyć pierwszą prawdziwą aplikację internetową. Wystarczy już prymitywnych namiastek gier, w których na jednowymiarowej planszy pływa jeden okręt. W tym rozdziale wykonasz pełne doświadczenie: dużą, atrakcyjną planszę do gry, wiele okrętów oraz obsługę wprowadzania danych przez użytkownika. Struktura strony, na której będzie prowadzona gra, powstanie w języku HTML, jej wygląd określony zostanie przy użyciu stylów CSS, a zachowanie samej gry napisane w języku JavaScript. Przygotuj się: to będzie jazda na całego, rozdział, w którym pełnym gazem będziesz zmierzać w kierunku pisania naprawdę poważnego kodu. Tym razem napiszemy PRAWDZIWĄ grę w okręty Krok wstecz… do HTML i CSS Tworzenie strony HTML: postać ogólna Dodawanie stylów Stosowanie klas hit i miss Jak zaprojektować grę? Implementacja widoku Jak działa metoda displayMessage? Jak działają metody displayHit oraz displayMiss? Model W jaki sposób będziemy reprezentować okręty? Implementacja obiektu modelu Rozmyślamy o metodzie fire Implementacja kontrolera Przetwarzanie pola wskazanego przez użytkownika Planowanie kodu… Implementacja funkcji parseGuess W międzyczasie w kontrolerze… Dodanie procedury obsługi zdarzeń do przycisku Ognia! Przekazywanie współrzędnych do kontrolera Jak rozmieszczać okręty? Implementacja metody generateShip Generacja początkowego pola okrętu Dokończenie metody generateShip 1 t ę r k O A B C D E F G Okręt2 Okręt3 A R T E N I E I F 0 1 2 3 4 5 6 344 345 346 350 353 355 357 357 359 362 364 367 368 375 376 377 378 381 385 386 390 391 392 393 17 Kup książkęPoleć książkę Spis treści 9 Programowanie asynchroniczne Obsługa zdarzeń Po przeczytaniu tego rozdziału zdasz sobie sprawę z tego, że to już nie są przelewki i nie jesteśmy już w Kansas. Do tej pory pisałeś kod, który zazwyczaj wykonywany był od samego początku do końca — oczywiście Twój kod mógł być nieco bardziej skomplikowany i zawierać kilka funkcji, obiektów i metod, jednak w jakimś momencie ten kod po prostu był wykonany wiersz po wierszu. Cóż, jest nam bardzo przykro, że mówimy Ci to tak późno, jednak typowy kod JavaScript nie jest pisany w taki sposób. Kod pisany w tym języku reaguje na zdarzenia. Jakiego rodzaju zdarzenia? Może to być kliknięcie strony przez użytkownika, przesłanie danych z serwera, upływ pewnego okresu czasu w przeglądarce, jakaś zmiana wprowadzona w DOM oraz wiele innych. W rzeczywistości, w niewidoczny dla nas sposób, w przeglądarce cały czas zachodzą jakieś zdarzenia. W tym rozdziale jeszcze raz przemyślisz swoje podejście do sposobu pisania kodu JavaScript i dowiesz się, dlaczego trzeba pisać kod reagujący na zdarzenia oraz jak należy to robić. Czym są zdarzenia? Czym jest procedura obsługi zdarzeń? Jak napisać pierwszą procedurę obsługi zdarzeń? Jazda próbna procedury obsługi zdarzeń Poznajemy zdarzenia, pisząc grę Implementacja gry Jazda próbna Dodajmy więcej obrazków Teraz musimy przypisać tę samą procedurę obsługi zdarzeń do właściwości onclick każdego obrazka Jak użyć tej samej funkcji do obsługi wszystkich obrazków? Jak działa obiekt zdarzenia? Zaprzęgamy obiekt zdarzenia do pracy Testujemy obiekt zdarzenia i właściwość target Zdarzenia i kolejki Jeszcze więcej zdarzeń Jak działa funkcja setTimeout? Kończenie gry Jazda testowa z licznikiem czasu 409 410 411 412 414 415 416 420 421 422 425 427 428 430 433 434 438 439 18 Kup książkęPoleć książkę 10 Funkcje pierwszej klasy Wyzwolone funkcje Poznaj funkcje, a potem baw się na całego. Każda sztuka, rzemiosło czy też dyscyplina sportowa mają swoją kluczową cechę, która odróżnia graczy przeciętnych od wirtuozów. W przypadku języka JavaScript jest to prawdziwe i dokładne zrozumienie funkcji. W języku JavaScript funkcje mają kluczowe znaczenie, a wiele technik służących do projektowania i organizacji kodu bazuje na zaawansowanej znajomości funkcji i umiejętności korzystania z nich. Droga prowadząca do poznania funkcji na takim poziomie jest interesująca i niejednokrotnie wymagająca dla mózgu, zatem dobrze się do niej przygotuj. W tym rozdziale będziesz się czuł jak dziecko oprowadzane przez pana Willy’ego Wonkę po fabryce czekolady — będziesz w nim kontynuował poznawanie funkcji w języku JavaScript, a przy okazji zobaczysz dziwaczne, wariackie i cudowne rzeczy. Tajemnicze, podwójne życie słowa kluczowego function Deklaracje funkcji a wyrażenia funkcyjne Przetwarzanie deklaracji funkcji I co dalej? Przeglądarka wykonuje kod Idziemy dalej… Instrukcja warunkowa O tym, dlaczego funkcje są także wartościami Czy wspominaliśmy już, że w JavaScripcie funkcje mają status „pierwszej klasy”? Latanie pierwszą klasą Piszemy kod do przetwarzania i sprawdzania pasażerów Przetwarzanie listy pasażerów Przekazywanie funkcji do funkcji Zwracanie funkcji z funkcji Pisanie kodu do wydawania napojów Pisanie kodu do wydawania napojów — inne podejście Przyjmowanie zamówień z wykorzystaniem funkcji pierwszej klasy Cola sieciowicka Jak działa metoda sort tablic? Łączymy wszystko w całość Weźmy teraz sortowanie na jazdę próbną 454 455 456 457 458 463 466 467 468 470 471 474 475 476 478 481 483 484 486 19 Spis treściKup książkęPoleć książkę Spis treści 11 Funkcje anonimowe, zasięg i domknięcia Poważne funkcje W poprzednim rozdziale rozłożyłeś funkcje na czynniki pierwsze, ale wciąż musisz się o nich jeszcze sporo dowiedzieć. W tym rozdziale będzie prawdziwa jazda na całego. Pokażemy Ci, jak naprawdę korzysta się z funkcji. To nieszczególnie długi rozdział, jednak bardzo intensywny, a po jego przeczytaniu siła wyrazu tworzonego przez Ciebie kodu JavaScript będzie większa, niż mógłbyś przypuszczać. Co więcej, mamy w nim zamiar przedstawić pewne ogólnie przyjęte idiomy i konwencje związane z tworzeniem i stosowaniem funkcji w języku JavaScript, dzięki czemu będziesz już mógł skorzystać z kodu pisanego przez współpracowników lub czerpanego z ogólnie dostępnych bibliotek JavaScript. A jeśli jeszcze nigdy nie słyszałeś o funkcjach anonimowych i domknięciach (ang. closure), to wiedz, że znalazłeś się w odpowiednim miejscu. Rzut oka na inną stronę funkcji… Jak używać funkcji anonimowych? Musimy ponownie pomówić o rozwlekłości Twojego kodu Kiedy funkcja zostaje zdefiniowana? To zależy… Co się właśnie stało? Dlaczego funkcja fly nie była zdefiniowana? Zagnieżdżanie funkcji Jaki wpływ na zasięg ma zagnieżdżanie funkcji? Krótka powtórka z zasięgu leksykalnego Miejsce, w którym zasięg leksykalny sprawia, że sprawy stają się interesujące Funkcje raz jeszcze Wywoływanie funkcji (po raz wtóry) Czym właściwie są domknięcia? Domykanie funkcji Zastosowanie domknięć w celu zaimplementowania magicznego licznika Zaglądamy za kulisy… Tworzenie domknięcia poprzez przekazanie wyrażenia funkcyjnego jako argumentu Domknięcia zawierają rzeczywiste środowisko, a nie jego kopię Tworzenie domknięć jako procedur obsługi zdarzeń Jak działa domknięcie liczące kliknięcia? 500 501 503 507 508 509 510 512 513 515 516 519 520 522 523 525 526 527 530 Chwila… Czy Judyta nie wspominała o domknięciach? Wygląda na to, że one są powiązane z tym, co robimy. Zobaczmy, czy będziemy mogli dowiedzieć się czegoś na ich temat i zagiąć Judytę. A niech to! Judyta znowu miała rację. 20 Kup książkęPoleć książkę 12 Zaawansowane sposoby konstruowania obiektów Tworzenie obiektów Dotychczas wszystkie obiekty tworzyłeś własnoręcznie. Opracowując każdy z nich, korzystałeś z literału obiektowego, w którym podawałeś wszystkie właściwości i metody. Na niewielką skalę takie rozwiązanie będzie się sprawdzać, jednak podczas tworzenia poważnego kodu będziesz potrzebował czegoś lepszego. Właśnie w tym miejscu do akcji wkraczają konstruktory obiektów. Konstruktory sprawiają, że tworzenie obiektów jest znacznie łatwiejsze, a wszystkie budowane obiekty mogą być zgodne z jednym wzorcem — oznacza to, że konstruktorów używamy po to, by zapewnić, że wszystkie obiekty będą miały te same właściwości i udostępniały te same metody. Kiedy korzystasz z konstruktorów, kod obiektów może być znacznie bardziej zwięzły i mniej podatny na występowanie błędów, zwłaszcza w przypadkach, gdy tworzysz bardzo dużo obiektów. Po przeczytaniu tego rozdziału będziesz stosował konstruktory z taką wprawą, jakbyś dorastał w Obiektowie. Tworzenie obiektów przy użyciu literałów obiektowych Stosowanie konwencji podczas tworzenia obiektów Prezentacja konstruktorów obiektów Jak utworzyć konstruktor? Jak należy używać konstruktorów? Sposób działania konstruktorów W konstruktorach można także umieszczać metody Nadszedł czas na produkcję masową Weźmy nowe samochody na jazdę próbną Nie zapominaj jeszcze o literałach obiektowych Przekazywanie argumentów przy użyciu literału obiektowego Modyfikacja konstruktora Car Zrozumieć instancje obiektów Nawet obiekty utworzone przy użyciu konstruktora mogą mieć własne właściwości Konstruktory stosowane w praktyce Obiekt Array Jeszcze więcej zabawy z wbudowanymi obiektami JavaScriptu 544 545 547 548 549 550 552 558 560 561 562 563 565 568 570 571 573 21 Spis treściKup książkęPoleć książkę Spis treści 13 Stosowanie prototypów Obiekty ekstramocne Nauka tworzenia obiektów była jedynie początkiem. Nadszedł czas na wzmocnienie obiektów. Potrzebujesz więcej sposobów, by tworzyć wzajemne związki pomiędzy obiektami oraz zapewniać możliwość współdzielenia kodu przez takie powiązane obiekty. Dodatkowo potrzebujesz także sposobów na rozszerzanie i zwiększanie możliwości istniejących obiektów. Innymi słowy, potrzebujesz więcej narzędzi. W tym rozdziale przekonasz się, że JavaScript dysponuje naprawdę użytecznym modelem obiektowym, choć jednocześnie jest on nieco odmienny od modeli stosowanych w innych obiektowych językach programowania. Zamiast typowego modelu obiektów bazującego na klasach, w JavaScripcie wykorzystano model bazujący na prototypach, w którym obiekty mogą dziedziczyć po innych obiektach i rozszerzać ich zachowania. A co on daje? Już wkrótce się przekonasz. A zatem zaczynajmy… Object toString() hasOwnProperty() // i więcej Prototyp Dog species: Psowate bark() run() wag() Prototyp ShowDog league: “Sieciowice” stack() bait() gait() groom() ShowDog name: Szatan , breed: terier szkocki , weight: 8 handler: Grzesiu Hej, zanim zaczniemy, mamy lepszy sposób rysowania diagramów obiektów Ponowna analiza konstruktorów: wielokrotnie używamy kodu, ale czy robimy to efektywnie? Czy powielanie metod jest poważnym problemem? Czym są prototypy? Dziedziczenie po prototypie Jak działa dziedziczenie? Przesłanianie prototypu Jak przygotować prototyp? Prototypy są dynamiczne Bardziej interesująca implementacja metody sit Jeszcze jeden raz: sposób działania właściwości sitting Jak zaprojektować psa pokazowego? Tworzenie łańcucha prototypów Jak działa dziedziczenie w łańcuchu prototypów? Tworzenie prototypu psa pokazowego Tworzenie instancji psa pokazowego Analiza wyników ćwiczenia Łańcuch prototypów nie kończy się na psie Wykorzystanie dziedziczenia na swoją korzyść… Przesłonięcie domyślnych metod Stosowanie dziedziczenia do własnych celów… Rozszerzanie wbudowanych obiektów Wielka Jednolita Teoria JavaScriptu Łączenie wszystkiego w całość Co dalej? 585 586 588 589 590 591 593 596 602 604 605 609 611 612 614 618 621 627 628 630 632 633 633 22 Kup książkęPoleć książkę Pozostałości Dziesięć najważniejszych rzeczy (których nie opisaliśmy) Spis treści A 644 646 647 648 649 650 652 654 656 657 661 23 Opisaliśmy naprawdę sporo zagadnień i już niemal udało Ci się skończyć tę książkę. Będziemy za Tobą tęsknili, jednak zanim pozwolimy Ci odejść, musimy jeszcze coś powiedzieć, bo nie czulibyśmy się w porządku, wypuszczając Cię w świat bez tych informacji. Nie ma możliwości, byśmy w tym stosunkowo niewielkim rozdziale zdołali zmieścić wszystko, co ewentualnie mogłoby się przydać. Prawdę mówiąc, wcześniej zamieściliśmy w tym rozdziale wszystko to, co przydałoby się, żebyś wiedział o programowaniu w języku JavaScript, lecz musieliśmy zmniejszyć rozmiar czcionki do 0,00004 punktu. Wszystko się zmieściło, ale nikt nie był w stanie tego przeczytać. Dlatego większość tego tekstu odrzuciliśmy, pozostawiając tu jedynie Dziesięć Najważniejszych Zagadnień. I to naprawdę jest koniec tej książki. Oczywiście z wyjątkiem indeksu, który koniecznie musisz przeczytać! 1. jQuery 2. Więcej operacji na DOM 3. Obiekt window 4. Obiekt arguments 5. Obsługa wyjątków 6. Dodawanie procedur obsługi zdarzeń przy użyciu metody addEventListener 7. Wyrażenia regularne 8. Rekurencja 9. JSON 10. JavaScript po stronie serwera Skorowidz S Kup książkęPoleć książkę Kup książkęPoleć książkę 11. Funkcje anonimowe, zasięg i domknięcia poważne funkcje Od kiedy poznałem funkcje anonimowe, moja siła wyrazu powiększyła się o 200 . W poprzednim rozdziale rozłożyłeś funkcje na czynniki pierwsze, ale wciąż musisz się o nich jeszcze sporo dowiedzieć. W tym rozdziale będzie prawdziwa jazda na całego. Pokażemy Ci, jak naprawdę korzysta się z funkcji. To nieszczególnie długi rozdział, jednak bardzo intensywny, a po jego przeczytaniu siła wyrazu tworzonego przez Ciebie kodu JavaScript będzie większa, niż mógłbyś przypuszczać. Co więcej, mamy w nim zamiar przedstawić pewne ogólnie przyjęte idiomy i konwencje związane z tworzeniem i stosowaniem funkcji w języku JavaScript, dzięki czemu będziesz już mógł skorzystać z kodu pisanego przez współpracowników lub czerpanego z ogólnie dostępnych bibliotek JavaScript. A jeśli jeszcze nigdy nie słyszałeś o funkcjach anonimowych i domknięciach (ang. closure), to wiedz, że znalazłeś się w odpowiednim miejscu. A może słyszałeś o domknięciach, lecz nie wiesz, co to jest? Tym bardziej jest to rozdział, który powinieneś przeczytać! to jest nowy rozdział� 499 Kup książkęPoleć książkę Wprowadzenie do funkcji anonimowych Rzut oka na inną stronę funkcji… Poznałeś już dwie strony funkcji: tę formalną, deklaratywną stronę funkcji oraz znacznie bardziej ekspresyjną stronę wyrażeń funkcyjnych. A teraz nadszedł czas, by przedstawić ich jeszcze inną, interesującą stronę, czyli funkcje anonimowe. Mówiąc o funkcjach anonimowych, mamy na myśli funkcje, które nie mają nazwy. Jak coś takiego jest możliwe? No cóż, kiedy tworzymy funkcje z wykorzystaniem deklaracji, bez wątpienia mają one nazwy. Jednak w przypadku, gdy budujemy funkcje przy użyciu wyrażeń funkcyjnych, nie musimy podawać ich nazw. Pewnie sobie pomyślałeś, że to całkiem interesujące i zapewne naprawdę można tak zrobić, ale co z tego? Kiedy użyjemy funkcji anonimowych, niejednokrotnie możemy znacząco skrócić nasz kod, a także sprawić, że będzie bardziej zwięzły i czytelny, efektywniejszy i łatwiejszy w utrzymaniu. A zatem, przekonajmy się, jak można używać funkcji anonimowych. Zaczniemy od fragmentu kodu, który poznałeś już wcześniej, i pokażemy, jak wykorzystywać funkcje anonimowe. To jest procedura obsługi zdarzeń load, którą tworzymy w standardowy sposób. Najpierw definiujemy funkcję. Funkcja ta ma nazwę handler. function handler() { alert(”O tak, strona została wczytana!”); } window.onload = handler; Następnie zapisujemy tę funkcję we właściwości onload obiektu window, używając jej nazwy handler. A kiedy strona zostanie wczytana, przeglądarka wywoła funkcję handler. Zaostrz ołówek Skorzystaj ze swojej wiedzy na temat funkcji i zmiennych, aby wskazać, które z poniższych stwierdzeń są prawdziwe. Zmienna handler zawiera referencję do funkcji.   Kiedy przypisujemy handler właściwości   window.onload, zapisujemy w niej referencję do funkcji. Jedynym powodem istnienia zmiennej handler jest zapisanie jej we właściwości window.onload. Już nigdy więcej nie użyjemy funkcji handler, gdyż jest to kod, który z założenia ma być wykonywany wyłącznie podczas pierwszego wczytania strony.  Dwukrotne wywoływanie procedury obsługi zdarzeń load nie jest dobrym pomysłem — może ono doprowadzić do wystąpienia problemów, gdyż ten kod służy zazwyczaj do wykonywania czynności związanych z inicjalizacją całej strony. ¨ Wyrażenia funkcyjne tworzą referencje do funkcji. ¨ Czy wspominaliśmy, że przypisując funkcję handler właściwości window.onload, zapisujemy w niej referencję do funkcji? 500 Rozdział 11 . Kup książkęPoleć książkę Funkcje anonimowe, zasięg i domknięcia Jak używać funkcji anonimowych? A zatem chcemy utworzyć funkcję do obsługi zdarzeń load, wiemy jednak, że jest to „funkcja jednorazowa”, gdyż zdarzenie to jest generowane tylko jeden raz podczas całego okresu prezentacji strony w przeglądarce. Możemy także zauważyć, że we właściwości window.onload jest zapisywana referencja do funkcji — a konkretnie rzecz biorąc, referencja do funkcji handler. Ponieważ jednak funkcja ta jest przeznaczona tylko do jednokrotnego użycia, zatem określanie jej nazwy jest niepotrzebne, gdyż używamy jej jedynie po to, by zapisać referencję we właściwości window.onload. Zastosowanie funkcji anonimowej umożliwia oczyszczenie naszego kodu. Funkcja anonimowa jest po prostu wyrażeniem funkcyjnym, pozbawionym nazwy i zapisanym w miejscu, w którym normalnie użylibyśmy referencji do funkcji. Aby jednak to wszystko ze sobą powiązać, przeanalizujemy przykład wykorzystania wyrażenia funkcyjnego w sposób anonimowy. function handler() { alert(”O tak, strona została wczytana!”); } window.onload = handler; Najpierw usuwamy zmienną handler, tworząc tym samym wyrażenie funkcyjne. function () { alert(”O tak, strona została wczytana!”); } window.onload = ; Następnie przypisujemy je bezpośrednio właściwości window.onload. window.onload = function() { alert(”O tak, strona została wczytana!”); } Teraz kod jest znacznie bardziej zwarty. Niezbędną funkcję przypisujemy bezpośrednio właściwości onload. Oprócz tego, nie tworzymy nazwy funkcji, która przypadkowo mogłaby zostać użyta w innym miejscu kodu (w końcu nazwa „handler” jest stosowana dosyć często!). Rany, popatrz! Nie ma nazwy! Teraz procedura obsługi została przypisana bezpośrednio właściwości window.onload, bez konieczności stosowania niepotrzebnej nazwy. WYSIL Szare komórkI Czy w którymś z przykładów przedstawionych wcześniej w tej książce były używane funkcje anonimowe, choć nie uprzedzaliśmy o tym? Podpowiedź: może ukrywają się gdzieś w Twoich obiektach? jesteś tutaj� 501 Kup książkęPoleć książkę Ćwiczenia z funkcji anonimowych Zaostrz ołówek Przedstawiony poniżej fragment kodu zapewnia kilka możliwości zastosowania funkcji anonimowych. Skorzystaj z nich i użyj funkcji anonimowych wszędzie tam, gdzie to możliwe. Możesz przekreślić stary kod i obok napisać nowy. I jeszcze jedna rzecz: zakreśl wszystkie anonimowe funkcje, które już są używane. window.onload = init; var cookies = { instructions: ”Wstępne rozgrzewanie do 175 stopni...”, bake: function(time) { console.log(”Wypiekam ciasteczka.”); setTimeout(done, time); } }; function init() { var button = document.getElementById(”bake”); button.onclick = handleButton; } function handleButton() { console.log(”Już można wypiekać ciasteczka.”); cookies.bake(2500); } function done() { alert(”Ciasteczka są gotowe, wyciągnij je, by przestygły.”); console.log(”Chłodzenie ciasteczek.”); var cool = function() { alert(”Ciasteczka są już zimne, można je jeść!”); }; setTimeout(cool, 1000); } 502 Rozdział 11 . Kup książkęPoleć książkę Funkcje anonimowe, zasięg i domknięcia Musimy ponownie pomówić o rozwlekłości Twojego kodu Bardzo nam się nie podoba, że musimy wracać do tego zagadnienia, zwłaszcza że poświęciłeś dużo wysiłku na naukę funkcji — wiesz, jak je wywoływać, jak przypisywać zmiennym, jak przekazywać do innych funkcji i jak zwracać jako wynik wykonania innych funkcji — jednak wciąż pisany przez Ciebie kod jest bardziej rozwlekły, niż to konieczne (można by także powiedzieć, że nie jesteś tak ekspresyjny, jak mógłbyś być). Przyjrzyj się poniższemu przykładowi. To zwyczajna funkcja o nazwie cookieAlarm, która wyświetla komunikat informujący, że ciasteczka są już gotowe. function cookieAlarm() { alert(”Już czas wyjąć ciasteczka z piekarnika.”); }; setTimeout(cookieAlarm, 600000); Wygląda na to, że ciasteczka będą gotowe za 10 minut… tak tylko mówię. A tu bierzemy tę funkcję i przekazujemy ją jako argument wywołania metody setTimeout. Gdybyś zapomniał, to ten czas jest wyrażony w milisekundach, a zatem 1000 · 60 · 10 = 600 000. Choć ten kod wygląda całkiem dobrze, jednak po zastosowaniu funkcji anonimowej możemy go nieco skrócić. W jaki sposób? No cóż… Pomyśl o zmiennej cookieAlarm umieszczonej w wywołaniu metody setTimeout. To zmienna, która odwołuje się do funkcji, a zatem w momencie wywoływania metody setTimeout jest do niej przekazywana referencja do funkcji. Już wiesz, że użycie zmiennej zawierającej referencję do funkcji jest jednym z kilku sposobów uzyskania takiej referencji, jednak — podobnie jak w przedstawionym kilka stron wcześniej przykładzie z właściwością window.onload — także i tu możemy skorzystać z funkcji anonimowej. Zmodyfikujmy zatem ten kod, używając w nim wyrażenia funkcyjnego. Teraz zamiast zmiennej w wywołaniu metody setTimeout przekazujemy inną funkcję, zapisując jej kod bezpośrednio w wywołaniu. Zwróć szczególną uwagę na zastosowaną składnię. Użyliśmy całego wyrażenia funkcyjnego, kończącego się zamykającym nawiasem klamrowym, które zamknęliśmy przecinkiem umieszczonym przed kolejnym argumentem, dokładnie tak samo, jak robimy w przypadku wszystkich innych argumentów w wywołaniach funkcji. setTimeout(function() { alert(”Już czas wyjąć ciasteczka z piekarnika.”); }, 600000); Zapisaliśmy nazwę wywoływanej metody, setTimeout, za nią nawias otwierający i pierwszy argument wywołania — wyrażenie funkcyjne. A tu za wyrażeniem funkcyjnym zapisaliśmy drugi argument. jesteś tutaj� 503 Kup książkęPoleć książkę Formatowanie anonimowych wyrażeń funkcyjnych Kogo próbujecie nabrać? Taka instrukcja tylko wprowadzi zamieszanie. Kto chciałby czytać taki długi wiersz kodu? A poza tym co zrobić, jeśli funkcja będzie długa i skomplikowana? W krótkim kodzie taka funkcja zapisana w jednym wierszu jest w porządku. Jednak w pozostałych przypadkach masz rację, taki zapis byłby raczej kiepskim pomysłem. Jednak, jak wiesz, w kodzie JavaScript można używać dowolnie wielu odstępów, zatem możemy umieścić w naszym kodzie tak dużo odstępów i znaków nowego wiersza, ile trzeba, by poprawić jego czytelność. Poniżej przedstawiliśmy nową, lepiej sformatowaną postać wywołania metody setTimeout z poprzedniej strony. Dodaliśmy tu jedynie trochę tzw. białych znaków, czyli znaków odstępu i nowego wiersza. setTimeout(function() { alert(”Już czas wyjąć ciasteczka z piekarnika.”); }, 600000); Cieszymy się, że poruszyłaś ten problem, gdyż teraz nasz kod jest znacznie bardziej czytelny. 504 Rozdział 11 .Kup książkęPoleć książkę Funkcje anonimowe, zasięg i domknięcia Hej, chwilkę… Chyba rozumiem. Ponieważ wyrażenia funkcyjne zwracają referencję do funkcji, zatem możemy używać ich wszędzie tam, gdzie są oczekiwane referencje do funkcji. Trochę się nagadałeś, ale faktycznie trafiłeś w sedno. To naprawdę jest jedno z kluczowych zagadnień, niezbędnych do zrozumienia, że funkcje są wartościami pierwszej klasy. Jeśli Twój kod oczekuje referencji do funkcji, w tym miejscu zawsze możesz umieścić wyrażenie funkcyjne, ponieważ po przetworzeniu daje ono referencję do funkcji. Jak się właśnie przekonałeś, jeśli argumentem ma być funkcja, nie ma sprawy — możesz zamiast niej przekazać wyrażenie funkcyjne (które przed wykonaniem wywołania zostanie zastąpione referencją do funkcji). To samo dotyczy sytuacji, gdy z jednej funkcji musisz zwrócić inną funkcję — możesz zwrócić wyrażenie funkcyjne. jesteś tutaj� 505 Kup książkęPoleć książkę Pytania o funkcje anonimowe Ćwiczenie Teraz upewnimy się, że dobrze zapamiętałeś składnię używaną do przekazywania anonimowych wyrażeń funkcyjnych w wywołaniach innych funkcji. Zmień poniższy kod tak, by zamiast zmiennej (w tym przypadku vaccine) argumentem wywołania było anonimowe wyrażenie funkcyjne. function vaccine(dosage) { if (dosage 0) { inject(dosage); } } administer(patient, vaccine, time); Tu zapisz swoją odpowiedź. I nie zapomnij sprawdzić odpowiedzi, zanim podejmiesz dalszą lekturę! P: Stosowanie funkcji anonimowych w taki sposób wydaje się bardzo zawiłe. Czy naprawdę muszę o tym wiedzieć? O: Owszem, musisz. Anonimowe wyrażenia funkcyjne bardzo często są używane w kodzie JavaScript, jeśli zatem chcesz nauczyć się analizy kodu napisanego przez innych programistów lub zrozumieć działanie bibliotek JavaScript, musisz wiedzieć, jak one działają i jak je rozpoznawać w kodzie. P: Czy stosowanie anonimowych wyrażeń funkcyjnych jest lepsze? Uważam, że jedynie komplikuje kod i sprawia, że trudno go czytać i analizować. Nie istnieją głupie pytania O: Poczekaj trochę. Po pewnym czasie, kiedy zobaczysz kod, taki jak ten, znacznie łatwiej będzie Ci go analizować, a naprawdę istnieje bardzo wiele sytuacji, w których taka składnia pozwala zmniejszyć złożoność kodu, sprawia, że jest bardziej przejrzysty, a nasze intencje — łatwiejsze do zauważenia. Z drugiej strony, przesadne wykorzystanie tej techniki na pewno może sprawić, że kod będzie trudniejszy do zrozumienia. Jeśli jednak zaczniesz jej używać, po pewnym czasie stanie się łatwiejsza i bardziej przydatna. Na pewno spotkasz się z wieloma przykładami kodu, który w bardzo dużym stopniu korzysta z funkcji anonimowych, zatem dołączenie tej techniki do swojego przybornika z narzędziami programistycznymi jest dobrym pomysłem. P: Skoro funkcje pierwszej klasy są tak użyteczne, to dlaczego nie ma ich w innych językach programowania? O: Ależ są (a ludzie, którzy pracują nad językami, w których ich nie ma, zaczynają rozważać ich dodanie). Przykładowo funkcje pierwszej klasy, takie jak w JavaScripcie, są dostępne w językach Scheme i Scala. Inne języki, takie jak PHP, Java (w najnowszej wersji), C# oraz Objective C, udostępniają większość lub niektóre z ich możliwości. Wraz ze wzrostem liczby osób rozpoznających zalety posiadania funkcji pierwszej klasy w używanym języku programowania coraz więcej języków zaczyna je udostępniać. Jednak każdy język robi to nieco inaczej, zatem badając analogiczne możliwości w innych językach, musisz się przygotować na pewne różnice. 506 Rozdział 11 . Kup książkęPoleć książkę Funkcje anonimowe, zasięg i domknięcia Kiedy funkcja zostaje zdefiniowana? To zależy… Jest jeszcze jedna, interesująca rzecz dotycząca funkcji, o której dotąd nie wspominaliśmy. Czy pamiętasz, że przeglądarka przetwarza kod JavaScript dwukrotnie? W ramach pierwszego przebiegu przetwarzane są wszystkie deklaracje funkcji, a odnalezione funkcje zostają zdefiniowane. Natomiast podczas drugiego przebiegu przeglądarka wykonuje kod JavaScript liniowo, od początku do końca; właśnie podczas tego przebiegu są przetwarzane wyrażenia funkcyjne. A to z kolei określa, gdzie i kiedy będziemy mogli wywoływać funkcje w kodzie. Aby przekonać się, co to wszystko naprawdę oznacza, przeanalizujemy konkretny przykład. Poniżej przedstawiliśmy kod z poprzedniego rozdziału, w którym wprowadziliśmy nieznaczne zmiany. Spróbujmy go wykonać. Zaczynamy od samego początku kodu i szukamy umieszczonych w nim deklaracji. 1 4 Ponownie zaczynamy do początku kodu, jednak tym razem zaczynamy go wykonywać. WAŻNE: Przeczytaj to zgodnie z kolejnością cyfr. Zacznij od 1, potem przejdź do 2 itd. var migrating = true; 5 Tworzymy zmienną migrating i zapisujemy w niej wartość true. Zwróć uwagę, że przenieśliśmy tę instrukcję warunkową z końca kodu na jego początek. if (migrating) { quack(4); fly(4); } 6 Wyrażenie warunkowe ma wartość true, więc wykonujemy blok kodu. 7 Pobieramy referencję do funkcji ze zmiennej quack i wywołujemy ją, przekazując do niej wartość 4. 8 Pobieramy referencję do funkcji ze zmiennej fly… Chwila, ta zmienna jeszcze nie została zdefiniowana! var fly = function(num) { for (var i = 0; i num; i++) { console.log( Latam! ); } }; 2 Znaleźliśmy deklarację funkcji. Tworzymy zatem tę funkcję i zapisujemy ją w zmiennej quack. function quack(num) { for (var i = 0; i num; i++) { console.log( Kwak! ); } } 3 Docieramy do końca kodu. Udało się znaleźć tylko jedną deklarację funkcji. jesteś tutaj� 507 Kup książkęPoleć książkę Kiedy są definiowane funkcje Co się właśnie stało? Dlaczego funkcja fly nie była zdefiniowana? No dobrze, mogliśmy się przekonać, że funkcja fly nie jest zdefiniowana, kiedy spróbowaliśmy ją wykonać, ale dlaczego tak się stało? Przecież funkcja quack zadziałała bez problemów. Jak już pewnie odgadłeś, funkcja fly — w odróżnieniu od funkcji quack, która została zdefiniowana podczas pierwszego przebiegu przetwarzania kodu, gdyż została utworzona przy użyciu deklaracji — jest definiowana podczas drugiego przebiegu, w trakcie którego kod jest wykonywany od początku do końca. Jeszcze raz przyjrzyjmy się naszemu przykładowi. Kiedy będziemy przetwarzać ten kod i spróbujemy wywołać quack, wszystko zadziała zgodnie z oczekiwaniami, gdyż funkcja quack została zdefiniowana podczas pierwszego przebiegu przetwarzania kodu. Konsola JavaScript Kwak! Kwak! Kwak! Kwak! TypeError: undefined is not a function To się dzieje, kiedy spróbujemy wywołać funkcję, która nie jest zdefiniowana. Jednak kiedy spróbujemy wywołać funkcję fly, zostanie wyświetlony błąd, gdyż funkcja ta nie została jeszcze zdefiniowana… …a zostanie zdefiniowana dopiero w momencie wykonania tej instrukcji, czyli po wywołaniu funkcji fly. var migrating = true; if (migrating) { quack(4); fly(4); } var fly = function(num) { for (var i = 0; i num; i++) { console.log(”Latam!”); } }; function quack(num) { for (var i = 0; i num; i++) { console.log(”Kwak!”); } } Możesz zobaczyć komunikat o błędzie przypominający przedstawiony tutaj (jego postać zależy od używanej przeglądarki): TypeError: Property ‘fly’ of object [object Object] is not a function. Co to wszystko oznacza? Zacznijmy od tego, że oznacza to, iż deklaracje funkcji można umieszczać w dowolnym miejscu kodu — na jego początku, końcu oraz pośrodku — a ich wywołania także mogą być umieszczane w dowolnych miejscach. Deklaracje tworzą funkcje, które są zdefiniowane w całym kodzie (rozwiązanie to jest określane jako podnoszenie lub windowanie, ang. hoisting). Oczywiście w przypadku wyrażeń funkcyjnych sprawa wygląda inaczej, gdyż one nie będą zdefiniowane, aż do momentu, gdy zostaną wykonane. A zatem jeśli nawet przypiszesz wyrażenie funkcyjne zmiennej globalnej, jak zrobiliśmy w przypadku zmiennej fly, nie będziesz mógł użyć jej do wywołania funkcji, aż do momentu, gdy zostanie ona zdefiniowana. I jeszcze jedno. Obie funkcje w powyższym przykładzie mają zasięg globalny, co oznacza, że kiedy już zostaną zdefiniowane, będą widoczne w całym kodzie. Trzeba także pamiętać o funkcjach zagnieżdżonych — czyli funkcjach definiowanych wewnątrz innych funkcji — gdyż ma to wpływ na ich zasięg. Zobacz sam… 508 Rozdział 11 . Kup książkęPoleć książkę Funkcje anonimowe, zasięg i domknięcia Zagnieżdżanie funkcji Definiowanie funkcji wewnątrz innej funkcji jest całkowicie dopuszczalne. Oznacza to, że wewnątrz jednej funkcji można umieścić deklarację innej lub wyrażenie funkcyjne. A jak to działa? Oto krótka odpowiedź na to pytanie: jedyną różnicą pomiędzy funkcją zdefiniowaną na najwyższym poziomie kodu a funkcją zdefiniowaną wewnątrz innej jest ich zasięg. Innymi słowy, umieszczenie jednej funkcji wewnątrz innej ma wpływ na to, w których miejscach kodu będzie ona widoczna. Aby zrozumieć to zagadnienie, rozszerzymy nieco nasz przykład, dodając do niego zagnieżdżone deklaracje funkcji oraz wyrażenia funkcyjne. Tutaj dodajemy deklarację funkcji o nazwie wingFlapper, umieszczoną wewnątrz wyrażenia funkcyjnego fly. A tutaj ją wywołujemy. Tu dodajemy wyrażenie funkcyjne, którego wynik jest zapisywany w zmiennej quacker; przy czym zarówno wyrażenie, jak i zmienna są umieszczone wewnątrz deklaracji funkcji quack. A tutaj ją wywołujemy. var migrating = true; var fly = function(num) { var sound = ”Latam!”; function wingFlapper() { console.log(sound); } for (var i = 0; i num; i++) { wingFlapper(); } }; function quack(num) { var sound = ”Kwak!”; var quacker = function() { console.log(sound); }; for (var i = 0; i num; i++) { quacker(); } } if (migrating) { quack(4); fly(4); } Przenieśliśmy ten blok kodu na sam koniec, zatem wywołanie funkcji fly nie będzie już przysparzać problemów. Ćwiczenie Weź ołówek i zaznacz, jakie fragmenty powyższego kodu obejmuje zasięg funkcji fly, quack, wingFlapper oraz quacker. Zaznacz także, które fragmenty kodu obejmuje zasięg tych funkcji, lecz jednocześnie funkcje te nie są tam zdefiniowane. jesteś tutaj� 509 Kup książkęPoleć książkę Wszystko, co zostało zdefiniowane na najwyższym poziomie kodu, ma zasięg globalny. Dlatego zarówno fly, jak i quacker będą zmiennymi globalnymi. Pamiętaj jednak, że funkcja fly będzie zdefiniowana dopiero po przetworzeniu wyrażenia funkcyjnego. Funkcja wingFlapper jest definiowana przy użyciu deklaracji umieszczonej wewnątrz funkcji fly. Zatem jej zasięg obejmuje całą funkcję fly i będzie ona zdefiniowana w całym obszarze ciała tej funkcji. Funkcja quacker jest definiowana przy użyciu wyrażenia funkcyjnego, umieszczonego wewnątrz funkcji quack. A zatem jej zasięg obejmuje całą funkcję quack, jednak będzie ona zdefiniowana od momentu przetworzenia wyrażenia funkcyjnego aż do końca funkcji quack. Funkcja quacker będzie zdefiniowana tylko w tym fragmencie kodu. var migrating = true; var fly = function(num) { var sound = ”Latam!”; function wingFlapper() { console.log(sound); } for (var i = 0; i num; i++) { wingFlapper(); } }; function quack(num) { var sound = ”Kwak!”; var quacker = function() { console.log(sound); }; for (var i = 0; i num; i++) { quacker(); } } if (migrating) { quack(4); fly(4); } Zagnieżdżanie funkcji i ich zasięg Jaki wpływ na zasięg ma zagnieżdżanie funkcji? Funkcje zdefiniowane na głównym poziomie kodu mają zasięg globalny, natomiast funkcje zdefiniowane wewnątrz innych funkcji mają zasięg lokalny. Przeanalizujemy kod przedstawiony na poprzedniej stronie i sprawdzimy, jaki zasięg mają poszczególne funkcje. Jednocześnie zastanowimy się, gdzie każda z tych funkcji zostanie zdefiniowana (bądź też, gdzie będzie niezdefiniowana). Zauważ, że reguły określające, kiedy można się odwoływać do funkcji, są takie same wewnątrz funkcji, jak i na poziomie globalnym. A zatem jeśli jesteśmy wewnątrz funkcji i funkcja zagnieżdżona została zdefiniowana przy użyciu deklaracji, to funkcja ta będzie zdefiniowana w całym obszarze funkcji zewnętrznej. Z drugiej strony, jeśli funkcja wewnętrzna została zdefiniowana przy użyciu wyrażenia funkcyjnego, będzie ona zdefiniowana wyłącznie po jego przetworzeniu. 510 Rozdział 11 . Nie istnieją głupie pytania P: Kiedy przekazujemy wyrażenie funkcyjne do innej funkcji, to przekazywana funkcja musi zostać zapisana w parametrze, a następnie, wewnątrz funkcji zewnętrznej, jest traktowana jako zmienna lokalna. Czy tak? O: Dokładnie tak. Przekazywanie funkcji jako argumentu wywołania innej funkcji powoduje skopiowanie referencji do funkcji przekazywanej i zapisanie jej w zmiennej parametru funkcji wywoływanej. A taki parametr zawierający referencję do funkcji, jak każdy inny parametr, jest zmienną lokalną. Kup książkęPoleć książkę JavaScriptowe wyzwanie ekstremalne Potrzebujemy eksperta do spraw funkcji pierwszej klasy i słyszeliśmy, że Ty nim jesteś! Poniżej znajdziesz dwa fragmenty kodu i musisz nam pomóc w określeniu, co wykonują, bo utknęliśmy. Dla nas oba fragmenty wyglądają prawie identycznie, z tą różnicą, że jeden używa funkcji pierwszej klasy, a drugi nie. Na podstawie naszej wiedzy o zasięgu w języku JavaScript oczekiwaliśmy, że próbka nr 1 zwróci wartość 008, a próbka nr 2 wartość 007. A jednak obie próbki zwracają wartość 008! Czy możesz nam pomóc w zrozumieniu, dlaczego tak się dzieje? Sugerujemy, żebyś przyjął zdecydowaną opinię, zapisał ją na tej stronie, a następnie odwrócił kartkę. Próbka nr 1 var secret = 007 ; function getSecret() { var secret = 008 ; function getValue() { return secret; } return getValue(); } Pr óbka nr 2 getSecret(); var secret = 007 ; function getSecret() { var secret = 008 ; function getValue() { return secret; } return getValue; } var getValueFun = getSecret(); getValueFun(); Jeszcze nie patrz na rozwiązanie zamieszczone pod koniec rozdziału, wrócimy do tego wyzwania nieco później. 511 jesteś tutaj�Funkcje anonimowe, zasięg i domknięciaKup książkęPoleć książkę Zasięg leksykalny Krótka powtórka z zasięgu leksykalnego Skoro już jesteśmy przy temacie zasięgu, powtórzymy jeszcze raz informacje dotyczące działania zasięgu leksykalnego. Leksykalny oznacza, że zasięg zmiennej można określić na podstawie analizy struktury kodu, a nie trzeba z tym czekać do momentu jego realizacji. Tu mamy zmienną globalną o nazwie justAVar. var justAVar = ”Och, nie przejmuj się, jestem zmienną GLOBALNĄ!”; function whereAreYou() { var justAVar = ”Szara, zwyczajna zmienna LOKALNA.”; A ta funkcja definiuje nowy zasięg leksykalny… return justAVar; } var result = whereAreYou(); console.log(result); …w którym mamy zmienną lokalną o nazwie justAVar, przesłaniającą zmienną globalną o tej samej nazwie. Kiedy ta funkcja zostanie wywołana, zwraca wartość zmiennej justAVar. Tylko której? Używamy zasięgu leksykalnego, zatem odnajdujemy odpowiednią zmienną justAVar, patrząc na zasięg najbliższej funkcji. Jeśli zmiennej tam nie znajdziemy, szukamy jej w zasięgu globalnym. A zatem kiedy wywołamy funkcję whereAreYou, zwróci ona wartość lokalnej, a nie globalnej zmiennej justAVar. Konsola JavaScript Szara, zwyczajna zmienna LOKALNA. A teraz wprowadźmy funkcję zagnieżdżoną. var justAVar = ”Och, nie przejmuj się, jestem zmienną GLOBALNĄ!”; function whereAreYou() { var justAVar = ”Szara, zwyczajna zmienna LOKALNA.”; Tu jest ta sama funkcja. function inner() { return justAVar; } Jak wcześniej, przesłaniamy zmienną globalną. Lecz teraz dysponujemy funkcją zagnieżdżoną, która odwołuje się do zmiennej justAVar. Ale do której? Także w tym przypadku używamy zmiennej z najbliższej funkcji zawierającej dany fragment kodu. A zatem użyjemy tej samej zmiennej, co w poprzednim przykładzie. return inner(); } Zauważ, że funkcję inner wywołujemy w tym miejscu i zwracamy jej wynik. var result = whereAreYou(); console.log(result); A zatem kiedy wywołamy funkcję whereAreYou, zostanie wywołana funkcja inner, która zwróci wartość lokalnej, a nie globalnej zmiennej justAVar. Konsola JavaScript Szara, zwyczajna zmienna LOKALNA. 512 Rozdział 11 .Kup książkęPoleć książkę Funkcje anonimowe, zasięg i domknięcia Miejsce, w którym zasięg leksykalny sprawia, że sprawy stają się interesujące Wprowadźmy jeszcze jedną, małą modyfikację. Uważnie przyjrzyj się temu przykładowi, jest naprawdę trudny. var justAVar = ”Och, nie przejmuj się, jestem zmienną GLOBALNĄ!”; function whereAreYou() { var justAVar = ”Szara, zwyczajna zmienna LOKALNA.”; Tu nie wprowadziliśmy żadnych zmian, to te same zmienne i funkcje, co wcześniej. function inner() { return justAVar; } return inner; } var innerFunction = whereAreYou(); var result = innerFunction(); console.log(result); Jednak zamiast wywoływać funkcję inner, tym razem ją zwracamy. A zatem kiedy wywołamy whereAreYou, uzyskamy referencję do funkcji inner, którą zapisujemy w zmiennej innerFunction. Następnie wywołujemy tę funkcję, zapisujemy zwrócony przez nią wynik w zmiennej result, po czym go wyświetlamy. Kiedy zatem funkcja inner zostanie wywołana (jako innerFunction) w tym miejscu, której zmiennej justAVar użyje? Tej lokalnej czy globalnej? Znaczenie ma moment wywołania funkcji. Wywołujemy inner po jej zwróceniu, kiedy w bieżącym zasięgu dostępna jest globalna zmienna justAVar, a zatem zostanie wyświetlony łańcuch „Och, nie przejmuj się, jestem zmienną GLOBALNĄ!”. Nie tak szybko. W zasięgu leksykalnym znaczenie ma struktura, w której funkcja została zdefiniowana, a zatem wynikiem wywołania musi być wartość zmiennej lokalnej, czyli „Szara, zwyczajna zmienna LOKALNA.”. jesteś tutaj� 513 Kup książkęPoleć książkę Bójka o funkcje Ja mam rację! Kiedy kukiełki okładały się pięściami, sięgnęłam po specyfikację języka JavaScript i wygląda na to, że to my mieliśmy rację. Powyższy kod wyświetli komunikat: „Szara, zwyczajna zmienna LOKALNA.”. Mylisz się!!! Franek: Co masz na myśli, mówiąc, że to wy macie rację? To tak, jakbyście definiowali prawa fizyki albo coś takiego. Ta zmienna lokalna już nawet nie istnieje… Chodzi mi o to, że kiedy kończy się zasięg zmiennej, przestaje ona istnieć. Po prostu znika! Nie oglądałeś filmu TRON? Judyta: Tak może jest w Twoim słabym C++ lub w Javie, ale nie w JavaScripcie. Kuba: Poważnie, jak to możliwe? Funkcja whereAreYou została wywołana i tyle, a zmienna lokalna justAVar nie może już przecież istnieć? Judyta: Gdybyście słuchali, co do was mówię… JavaScript nie działa w taki sposób. Franek: No dobra, rzuć nam jakąś garść informacji. Jak to działa? Judyta: Kiedy definiujemy funkcję inner, zmienna justAVar znajduje się w jej zasięgu. Zasięg leksykalny oznacza, że istotny jest sposób definiowania zmiennych; jeśli zatem używamy zasięgu leksykalnego, to zawsze wtedy, gdy wywołamy funkcję inner, przyjmie ona, że ta zmienna lokalna wciąż jest dla niej dostępna i może z niej korzystać. Franek: Ale, jak już powiedziałem, to wygląda tak, jakbyśmy zmieniali definicję praw fizyki. Funkcja whereAreYou, która zdefiniowała lokalną wersję zmiennej justAVar, została już wykonana i przestała istnieć. Judyta: To prawda. Funkcja whereAreYou została wykonana, lecz funkcja inner wciąż może skorzystać z jej zasięgu. Kuba: Ale jak? Judyta: No dobrze, zobaczmy zatem, co NAPRAWDĘ się dzieje, kiedy definiujemy i zwracamy funkcję… 514 Rozdział 11 . UWAGA REDAKCYJNA: Czy Józek naprawdę zmienił koszulkę na tej stronie? Kup książkęPoleć książkę Funkcje raz jeszcze Musimy coś wyznać. Nie powiedzieliśmy Ci wszystkiego o funkcjach. Nawet kiedy zapytałeś o to, na co faktycznie wskazują referencje do funkcji, uprościliśmy nieco odpowiedź. Powiedzieliśmy coś w stylu: „Na coś, co przypomina skrystalizowaną funkcję, zawierającą jej blok kodu”. Teraz jednak nadszedł czas, by
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Programowanie w JavaScript. Rusz głową!
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ą: