Download as pdf or txt
Download as pdf or txt
You are on page 1of 57

Head First JavaScript.

Edycja polska
Autor: Michael Morrison
Tumaczenie: Piotr Rajca
ISBN: 978-83-246-1548-3
Tytu oryginau: Head First JavaScript (Head First)
Format: 200x230, stron: 624

Poznaj jzyk JavaScript w niekonwencjonalny


i zadziwiajco skuteczny sposb!
Dzi statyczne witryny WWW gin w ogromnej masie podobnych sobie stron, przy
braku zainteresowania wspczesnych uytkownikw sieci. Aby si wyrni, trzeba
zaproponowa ogldajcym co innego ni tylko adnie sformatowany tekst i schludn
grafik. Jednym z pomysw na zwikszenie atrakcyjnoci witryny WWW jest
wprowadzenie na ni elementw interaktywnych. Istnieje wiele rozwiza sucych
do tworzenia takich elementw. Jednym z najczciej wykorzystywanych jest
JavaScript. Ten interpretowany po stronie przegldarki jzyk pozwala midzy innymi
na kontrolowanie niemal wszystkich elementw HTML w oparciu o obiektowy model
dokumentu (DOM), obsug zdarze generowanych przez uytkownika i weryfikacj
poprawnoci danych wprowadzanych do formularza.
Dziki ksice Head First JavaScript. Edycja polska poznasz JavaScript w nietypowy,
a przy tym bardzo skuteczny sposb. Poniewa zostaa ona napisana w oparciu
o najnowsze teorie uczenia si, byskawicznie przyswoisz sobie wiedz o tym jzyku.
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 obsugiwa pliki cookie
oraz procedury obsugi zdarze. Poznasz take techniki programowania obiektowego
i sposoby wykrywania czy usuwania bdw. Przeczytasz rwnie o technologii AJAX,
opierajcej si na jzyku JavaScript.
Podstawowe elementy JavaScript
Praca ze zmiennymi
Interakcja z przegldark
Wyraenia warunkowe i ptle
Organizacja kodu i korzystanie z funkcji
Obiektowy Model Dokumentu
Obiekty w JavaScript
Testowanie skryptw
Wykorzystanie JavaScript w technologii AJAX

Twj czas jest cenny wykorzystaj go na poznanie JavaScript


z pomoc nowoczesnych metod nauki!

Spis treci

Spis treci (podsumowanie)

Wprowadzenie

19

Interaktywna WWW. W odpowiedzi na wirtualny wiat

31

Przechowywanie danych. Wszystko ma swoje miejsce

61

Poznajemy klienta. W gb przegldarki

111

Podejmowanie decyzji. Jeli droga si rozwidla, nie wahaj si skrci

159

Ptle. Ryzykujc powtrzeniem

211

Funkcje. Redukuj i uywaj wielokrotnie

263

Formularze i sprawdzanie poprawnoci danych. Aby uytkownik


powiedzia nam wszystko

307

Modyfikacje stron WWW. Krojenie i przyprawianie HTML-a


przy uyciu DOM

359

Oywianie danych. Obiekty jako Frankendane

407

10

Tworzenie wasnych obiektw. Zrb to po swojemu, uywajc


wasnych obiektw

461

11

Zabijaj pluskwy na mier! Dobre skrypty na zej drodze

495

12

Dynamiczne dane. Szybkie i wraliwe aplikacje internetowe

545

Skorowidz

605

Spis treci (teraz na powanie)

Wprowadzenie
Twj mzg koncentruje si na JavaScripcie. Siedzisz, prbujc si czego nauczy,
ale Twj mzg twierdzi, e caa ta nauka nie jest wana. Twj mzg twierdzi: Lepiej zostawi
miejsce na jakie wane rzeczy, takie jak to, ktrych dzikich zwierzt naley unika albo czy
jedenie nago na snowboardzie jest dobrym pomysem, czy nie. W jaki zatem sposb moesz
przekona swj mzg, by uzna, e poznanie JavaScriptu to dla Ciebie kwestia ycia lub mierci?
Dla kogo jest ta ksika?

20

Wiemy, co sobie mylisz

21

Metapoznanie

23

Oto, co moesz zrobi, aby zmusi swj mzg do posuszestwa

25

Przeczytaj to

26

Zesp recenzentw

28

Podzikowania

29

Spis treci

Interaktywna WWW

W odpowiedzi na wirtualny wiat


Czy mczy Ci ju mylenie o WWW w kategoriach statycznych stron?
To ju widziaem i przerobiem. Takie rzeczy zazwyczaj nazywaj ksikami. Trzeba przyzna,
e doskonale si one nadaj do czytania i nauki, i w ogle s super. Ale nie s interaktywne.
To samo dotyczy take stron WWW, jeli nie uzyskaj one nieznacznej pomocy ze strony jzyka
JavaScript. Pewnie, e mona przesa formularz i moe nawet zastosowa tu i tam kilka trikw,
uywajc w tym celu umiejtnie napisanego kodu HTML i CSS, jednak takie rozwizania nie s
w stanie oywi martwych statycznych stron WWW. Prawdziwa interaktywno wymaga
znacznie wikszego wkadu intelektualnego i nakadu pracy, jednak zapewnia efekty, ktre
zwrc si z nawizk.
Uytkownicy (WWW) maj swoje potrzeby

32

To jakby rozmowa ze cian cakowity brak reakcji

33

A JavaScript odpowiada

34

wiata, kamera, interakcja!

36

Uyj znacznika <script>, by da przegldarce zna,


e piszesz kod JavaScript

41

Twoja przegldarka WWW poradzi sobie z kodem HTML,


CSS i JavaScript

42

Najlepszy wirtualny przyjaciel mczyzny potrzebuje TWOJEJ pomocy

45

Zapewnianie interaktywnoci iGazowi

46

Utworzenie strony WWW iGazu

47

Test

47

Zdarzenia JavaScript: udzielamy gosu iGazowi

48

Informowanie uytkownika przy wykorzystaniu funkcji

49

Dodanie powitania

50

A teraz zadbamy o to, by iGaz sta si naprawd interaktywny

52

Interakcja jest komunikacj DWUstronn

53

Dodajemy funkcj do pobrania imienia uytkownika

54

Byskawiczna powtrka: Co si przed chwil stao?

57

Testujemy iGaz w wersji 1.0

58

Spis treci

Przechowywanie danych

Wszystko ma swoje miejsce


W praktyce czsto nie dostrzegamy znaczenia, jakie ma posiadanie miejsca
do przechowywania swoich rzeczy. Korzystajc z jzyka JavaScript, na pewno zwrcimy
na to uwag. W tym przypadku nie mamy bowiem luksusu posiadania osobnej garderoby
lub garau na trzy samochody. W JavaScripcie wszystko musi mie swoje miejsce, a Twoim
zadaniem jest zadbanie, by faktycznie tak si stao. W tym rozdziale bdziemy si zajmowa
danymi oraz zagadnieniami, ktre ich dotycz jak je reprezentowa, przechowywa oraz jak
je odnale, kiedy zostan ju gdzie zapisane. Jako specjalista do spraw przechowywania danych
w JavaScripcie bdziesz w stanie zaj si dowolnym kodem, zapanowa nad chaosem obecnym
wrd uywanych w nim danych, dziki czemu bdziesz mg uporzdkowa go wedle swojej
woli, korzystajc przy tym z zalet wirtualnych etykiet i pojemnikw.

6 z nadzieniem
3 z lukrem
Odbierze Grzesiek za
20 minut

Twoje skrypty mog przechowywa dane

62

Skrypty myl w oparciu o typy danych

63

Stae zostaj TAKIE SAME, wartoci zmiennych mog si ZMIENIA

68

Zmienne pocztkowo nie maj wartoci

72

Inicjalizacja zmiennej przy uyciu znaku =

73

Stae s odporne na zmiany

74

A jak wygldaj nazwy?

78

Dozwolone i niedozwolone nazwy zmiennych oraz staych

79

Nazwy zmiennych czsto s zapisywane wedug notacji CamelCase

80

Planujemy stron zamwienia dla Donalda

84

Pierwsze podejcie do oblicze w formularzu zamwienia

86

Inicjuj swoje dane albo

89

NaN NIE jest liczb

90

Nie tylko liczby mona dodawa

92

parseInt() oraz parseFloat() konwersja acuchw znakw na liczby

93

Dlaczego w zamwieniu pojawiaj si dodatkowe pczki?

94

Donald odkrywa szpiegostwo ciastkarskie

98

Uyj metody getElementById(), by pobra dane z formularza

99

Weryfikacja danych w formularzu

100

Staraj si, by interfejs uytkownika by intuicyjny

105

Spis treci

Poznajemy klienta

W gb przegldarki
Czasami kod JavaScript musi wiedzie, co si dzieje w wiecie naokoo
niego. Twoje skrypty mog pocztkowo by tworzone jako kod umieszczany bezporednio
w stronach WWW, jednak w ostatecznoci i tak bd istnie i dziaa w wiecie kreowanym przez
przegldark WWW, nazywan take klientem. Sprytne skrypty czsto bd potrzeboway
pewnych informacji o wiecie, w ktrym yj; w takich sytuacjach mog zdoby te dane,
komunikujc si z przegldark. Niezalenie od tego, czy jest to okrelenie wymiarw ekranu,
czy te dostp do jakiego przycisku przegldarki, to utrzymujc dobre stosunki z przegldark,
skrypty mog bardzo wiele zyska.
Klienty, serwery i JavaScript

Tu zaczynamy!

Koniec!

112

Co przegldarka moe zrobi dla Ciebie?

114

iGaz musi reagowa bardziej wyrazicie

116

Liczniki czasu kojarz akcje z upywajcym czasem

118

Przerywanie dziaania licznika

119

Tworzenie licznika czasu przy uyciu funkcji setTimeout()

120

W zblieniu funkcja setTimeout()

121

Wiele rozmiarw ekranu, wiele skarg

125

Uyj obiektu document, by okreli szeroko okna przegldarki

126

Skorzystaj z obiektu document, by odczyta szeroko okna klienta

127

Okrelanie wymiarw obrazka iGazu

128

Wielko iGazu naley dostosowa do strony

129

W momencie zmiany wielkoci okna zgaszane jest zdarzenie onresize

133

Zdarzenie onresize skaluje obrazek iGazu

134

Czy mymy si ju spotkali? Rozpoznawanie uytkownika

136

Kady skrypt ma swj cykl yciowy

137

Ciasteczka mog istnie duej ni cykl ycia skryptu

138

Ciasteczka maj nazw i przechowuj warto poza tym mog wygasn

143

Twj kod JavaScript moe istnie POZA Twoj stron WWW

145

Przywitaj uytkownika ciasteczkiem

146

Teraz funkcja greetUser bazuje na ciasteczkach

147

Nie zapomnij o zapisaniu ciasteczka

148

Ciasteczka maj wpyw na bezpieczestwo przegldarek

150

wiat bez ciasteczek

152

Porozmawiaj z uytkownikiem, to lepsze ni nic

155

Spis treci

Podejmowanie decyzji

Jeli droga si rozwidla, nie wahaj si skrci


ycie polega na podejmowaniu decyzji. Stan czy jecha, miesza czy wstrzsa, i
na ugod czy do sdu Tak naprawd bez moliwoci podejmowania decyzji nic nigdy nie udaoby
si zrobi. To samo dotyczy JavaScriptu decyzje pozwalaj skryptom dokonywa wyboru
pomidzy rnymi moliwymi wynikami. To wanie podejmowanie decyzji tworzy histori
naszego skryptu, a swoj histori maj wszystkie skrypty, nawet te najbardziej prozaiczne.
Czy wirz w to, co wpisa uytkownik, i bez wahania zarezerwuj mu uczestnictwo w ekspedycji
badawczej Biaowiey? A moe bardzo dokadnie sprawdz wpisane informacje, by nie okazao
si, e tak naprawd uytkownik chciaby jedynie dojecha autobusem w okolice Biaowiey?
Sam musisz podj decyzj i dokona wyboru!
Szczliwy uczestniku, prosimy na scen!

160

Jeli to prawda, to co zrb

162

Instrukcja if przetwarza warunek, a nastpnie wykonuje operacj

163

Uyj instrukcji if, by wybra jedn z dwch opcji

165

Instrukcja if pozwala wybiera spord wielu opcji

166

Dodawanie klauzuli else do instrukcji if

167

Przebiegiem zdarze steruj zmienne

170

Brakuje jednak czci historii

171

Skadanie operacji w JavaScripcie

172

Mczy Ci podejmowanie decyzji przy uyciu instrukcji if/else?

178

Instrukcj if mona umieci wewntrz innej instrukcji if

179

Twoje funkcje kontroluj dziaanie stron

181

Pseudokod pozwala naszkicowa oglny obraz przygody

182

Nierwno kreskowego ludzika

186

!= Ech, Nie mam ci nic do powiedzenia

187

Podejmowanie decyzji z wykorzystaniem operatorw porwnania

188

Komentarze, puste miejsca i dokumentacja

190

Komentarze w JavaScripcie zaczynaj si od znakw //

191

Zakres i kontekst gdzie yj dane

193

Sprawd, gdzie s rozmieszczone zmienne w naszej przygodzie

194

Gdzie yj moje dane?

195

Jedna z piciu

198

Zagniedanie instrukcji if/else moe si sta skomplikowane

199

Instrukcje switch udostpniaj wiele opcji

201

Poznajemy szczegy instrukcji switch

202

Testowanie nowej wersji Przygody kreskowego ludzika

207

Spis treci

Ptle

Ryzykujc powtrzeniem
Niektrzy mwi, e powtrzenia to podstawa sukcesu. Oczywicie, e robienie
wci nowych i interesujcych rzeczy jest ekscytujce, lecz jednak codzienne ycie skada si
z czynnoci, ktre wielokrotnie powtarzamy. Maniakalne czyszczenie rk, nerwowe tiki bd
klikanie przycisku Odpowiedz wszystkim po odebraniu kadego dziwacznego lub miesznego
e-maila! No dobrze, moe w rzeczywistoci powtrzenia nie zawsze s takie znowu wspaniae.
Niemniej w wiecie JavaScriptu powtrzenia mog by niesychanie przydatne i uyteczne. Sam
nie wiesz, jak czsto pojawia si potrzeba kilkakrotnego wykonania pewnego fragmentu kodu
I wanie w takich sytuacjach w peni mona doceni zalety ptli. Gdyby nie one, musiaby
spdza bardzo duo czasu, wielokrotnie kopiujc i wklejajc ten sam fragment kodu.

Dostpne

X wskazuje miejsce

seat_avail.png

Zajte

Wybrane

seat_unavail.png

seat_select.png

10

212

Cay czas dja vu ptle for

213

Poszukiwanie skarbw z ptl for

214

Anatomia ptli for

215

Mandango wyszukiwarka miejsc dla prawdziwych macho

216

Najpierw sprawdzamy dostpno miejsc

217

Ptle, HTML i dostpno miejsc

218

Fotele s zmiennymi

219

Tablice gromadz wiele danych

220

Wartoci tablicy s zapisywane wraz z kluczami

221

Od JavaScriptu do HTML-a

225

Wizualizacja miejsc na stronie Mandango

226

Test: odnajdywanie pojedynczych wolnych miejsc

231

Co za duo, to niezdrowo ptle nieskoczone

232

Ptle zawsze musz mie warunek zakoczenia (albo nawet dwa!)

233

Przerwa w dziaaniu

234

Odkrywamy operatory logiczne

240

Powtrzenia do skutku dopki warunek jest speniony

244

Analiza ptli while

245

Zastosowanie odpowiedniej ptli do konkretnego zadania

247

Modelowanie danych reprezentujcych miejsca w kinie

253

Tablica tablic tablice dwuwymiarowe

254

Dwa klucze zapewniaj dostp do tablicy dwuwymiarowej

255

Dwuwymiarowe Mandango

257

Caa sala miejsc dla prawdziwych macho

260

Spis treci

Funkcje

Redukuj i uywaj wielokrotnie


Gdyby w wiecie JavaScriptu zaistnia jaki ruch rodowiskowy, to zapewne
na jego czele stanyby funkcje. Funkcje pozwalaj na pisanie bardziej efektywnego kodu
i sprawiaj, e atwiej mona go wielokrotnie uywa. Funkcje s zorientowane na wykonywanie
konkretnych zada i znaczco uatwiaj organizacj kodu. Wyglda to jak cakiem dobry yciorys!
W praktyce niemal wszystkie skrypty, moe za wyjtkiem tych najprostszych, mog skorzysta na
reorganizacji kodu i zastosowaniu funkcji. Cho trudno jest oceni znaczenie i wpyw przecitnej
funkcji, to jednak naley zaznaczy, e odgrywaj one znaczc rol w staraniach, by skrypty byy
moliwie jak najbardziej przyjazne dla rodowiska.
Matka wszystkich problemw

264

Funkcje jako narzdzia do rozwizywania problemw

266

Tworzenie funkcji w praktyce

267

Funkcje, ktre ju poznae

268

Lepsza klimatyzacja dziki wikszej iloci danych

271

Przekazywanie informacji do funkcji

272

Argumenty funkcji jako dane

273

Funkcje eliminuj powtarzajcy si kod

274

Tworzenie funkcji okrelajcej status miejsc

277

Funkcja setSeat() jeszcze bardziej poprawia kod aplikacji Mandango

279

Znaczenie informacji zwrotnych

281

Zwracanie danych z funkcji

282

Wiele szczliwych wartoci wynikowych

283

Odczyt statusu miejsca

287

Prezentacja statusu miejsca

288

Moemy poczy funkcj z obrazkiem

289

Powielanie kodu nigdy nie jest dobre

290

Separacja funkcjonalnoci od zawartoci

291

Funkcje s zwykymi danymi

292

Wywoania i odwoania do funkcji

293

Zdarzenia, funkcje zwrotne i atrybuty HTML

297

Okrelanie procedur obsugi zdarze przy uyciu odwoa do funkcji

298

Literay funkcyjne spiesz z odsiecz

299

Czym jest kojarzenie ?

300

Struktura strony HTML

303

11

Spis treci

Formularze i sprawdzanie poprawnoci danych

Aby uytkownik powiedzia nam wszystko


Nie musisz by ani szczeglnie grzeczny, ani chytry, by pobiera od
uytkownikw dane, korzystajc z moliwoci, jakie zapewnia JavaScript.
Nie ma natomiast adnych wtpliwoci co do tego, e musisz zachowa przy tym du ostrono
i uwag. Ludzie wykazuj dziwn tendencj do popeniania bdw, co oznacza, e nie moesz
z gry zakada, i informacje podawane przez uytkownikw bd precyzyjne bd prawidowe.
I tu do akcji wkracza JavaScript. Przekazujc informacje wpisane w polach formularza do
odpowiedniego kodu napisanego w tym jzyku, i to bezporednio po ich podaniu, moesz nie
tylko poprawi niezawodno aplikacji, lecz take nieco odciy serwer. Musimy oszczdza
cenn przepustowo czy na waniejsze rzeczy, takie jak wideo z zapierajcymi dech w piersiach
wyczynami kaskaderskimi lub urocze zdjcia naszego ulubionego zwierzaka.

ow
e

Formularz rejestracyjny Banerolotu

er
an
B

12

er y
ban
dniebne
lot po

la
ek

309

Kiedy HTML nie wystarcza

310

Dostp do danych formularzy

311

Weryfikacja danych poda za cigiem zdarze

313

Zdarzenia onblur tracimy ostro

314

Moesz uywa okienka informacyjnego do wywietlania komunikatw


o bdach

315

Weryfikacja pl w celu sprawdzenia, czy mamy co wicej ni nic

319

Weryfikacja bez wkurzajcych okienek dialogowych

320

Subtelniejsze metody weryfikacji danych

321

Wielko ma znaczenie

323

Weryfikacja dugoci danych

324

Weryfikacja kodu pocztowego

329

Weryfikacja daty

334

Niezwyke wyraenia regularne

336

Wyraenia regularne definiuj poszukiwane wzorce

337

Metaznaki reprezentuj wicej ni jeden znak

339

Tajniki wyrae regularnych kwantyfikatory

340

Weryfikacja danych przy uyciu wyrae regularnych

344

Dopasowywanie okrelonej liczby powtrze

347

Eliminacja trzycyfrowego roku przy uyciu tego lub tamtego

349

Niczego nie zostawiajmy przypadkowi

350

Czy teraz mnie syszysz? Weryfikacja numeru telefonu

351

Masz wiadomo weryfikacja adresw e-mail

352

Wyjtek jest regu

353

Dopasowywanie opcjonalnych znakw ze zbioru

354

Tworzenie funkcji weryfikujcej adres e-mail

355

Spis treci

Modyfikacje stron WWW

Krojenie i przyprawianie HTML-a przy uyciu DOM


Uzyskanie kontroli nad zawartoci stron WWW dziki wykorzystaniu
JavaScriptu w duym stopniu przypomina pieczenie. Nie wie si co prawda z takim
samym baaganem jednak z drugiej strony nie daje w efekcie tak smakowitych rezultatw. Niemniej
masz peny dostp do skadnikw HTML-a tworzcych stron WWW, a co wicej masz moliwo
modyfikowania przepisu tej strony. A zatem JavaScript pozwala na modyfikowanie kodu HTML
strony i dostosowywanie go do wasnych potrzeb, co daje bardzo ciekawe moliwoci. A wszystko
to dziki kolekcji standardowych obiektw, okrelanej mianem obiektowego modelu dokumentu
(w skrcie DOM, od angielskich sw Document Object Model).

Document

html

body

""

"Stoisz

strong

""

"w samym rodku lasu."

head

Funkcjonalny, lecz niezgrabny interfejs uytkownika ma znaczenie

360

Opisy scen bez okienek dialogowych

361

Dostp do elementw HTML

363

Blisze spotkanie z wewntrznym HTML-em

364

Aby zobaczy lasy i drzewa: obiektowy model dokumentu (DOM)

369

Twoja strona jest kolekcj wzw DOM

370

Poruszanie si po drzewie DOM przy uyciu waciwoci

373

Modyfikowanie wza tekstowego przy wykorzystaniu DOM

376

Przygoda standaryzowana

381

Projektujemy wiksze i lepsze opcje

383

Rozwaania nad zastpowaniem wzw tekstowych

384

Funkcja zastpujca tekst w wle

385

Dynamiczne opcje nawigacyjne to wietna rzecz

386

Interaktywne opcje decyzyjne s jeszcze lepsze

387

Kwestia stylu: CSS i DOM

388

Podmienianie stylw

389

Klasowe opcje

390

Test stylizowanych opcji decyzyjnych

391

Problemy z opcjami pusty przycisk

392

Modyfikacja stylw wedle zamwienia

393

adnych niepotrzebnych opcji

395

Wicej opcji, wiksza zoono

396

ledzenie drzewa decyzyjnego

398

Przekszta histori swoich decyzji na kod HTML

399

Produkcja kodu HTML

400

ledzenie przebiegu przygody

403

"sam"

13

Spis treci

Oywianie danych

Obiekty JavaScriptu nie s tak makabryczne, jak dobry lekarz mgby


przypuszcza. Niemniej s ciekawe, gdy cz rne elementy jzyka w jedn cao, ktra
ma wiksze moliwoci ni suma jej skadowych. Obiekty cz dane z akcjami, tworzc w ten
sposb nowy typ danych, ktry w znacznie wikszej mierze ni opisane wczeniej typy przypomina
co ywego. W efekcie moemy stworzy tablice, ktre same bd potrafiy posortowa swoj
zawarto, acuchy znakw dysponujce moliwoci samodzielnego przeszukiwania swojej
treci, a skryptom moe wyrosn sier i mog zacz wy do ksiyca! No dobra, te dwie
ostatnie rzeczy nie s moliwe, ale rozumiesz ju, o co chodzi.

Akcje
function prezentuj(co, kiedy, gdzie) {
...

Dane
var kto;
var co;

Obiekty jako Frankendane

var kiedy;

}
function dostarcz(kto) {
...
}

var gdzie;

Obiekt
function prezentuj
(co, kiedy, gdzie) {

14

...
var kto;
var co;
var kiedy;
var gdzie;

}
function dostarcz(kto) {
...
}

JavaScriptowa impreza

408

Dane + akcje = obiekt

409

Obiekt jest wacicielem danych

410

W odwoaniach do skadowych obiektu uywamy kropki

411

Niestandardowe obiekty rozszerzaj jzyk JavaScript

415

Tworzenie wasnego niestandardowego obiektu

416

Co jest w konstruktorze?

417

Powoujemy do ycia obiekty blogu

418

Potrzeba sortowania

423

Obiekt daty w JavaScripcie

424

Wyliczanie czasu

425

Ponowna analiza zagadnienia dat w blogu

426

Obiekt w obiekcie

427

Konwersja obiektw na acuchy znakw

430

Pobieranie konkretnych informacji o dacie

431

Tablice jak obiekty

434

Sortowanie tablic wedle wasnych potrzeb

435

atwiejsze sortowanie dziki literaom funkcyjnym

436

Przeszukiwanie wpisw w blogu

439

Przeszukiwanie zawartoci acucha znakw indexOf()

441

Przeszukiwanie tablicy blogu

442

Teraz dziaa take wyszukiwanie!

445

Obiekt Math jest obiektem organizacyjnym

448

Generowanie liczb losowych przy uyciu metody Math.random()

450

Zamiana funkcji na metod

455

Przedstawiamy pikny nowy obiekt Blog

456

Jakie s korzyci uycia obiektw na stronie MagicznaKostka?

457

Spis treci

Tworzenie wasnych obiektw

10

Zrb to po swojemu, uywajc wasnych obiektw


Gdyby to byo takie atwe, na pewno by sobie z tym sam poradzi. W wiecie
JavaScriptu nie ma gwarancji zwrotu poniesionych kosztw, jednak nikt nigdy nie bdzie Ci broni
robi wszystkiego po swojemu. Niestandardowe obiekty w JavaScripcie s odpowiednikiem
wietnej, wielkiej, gorcej, mistrzowskiej, okazyjnej promocji. To jeden niestandardowy kubek
kawy! A dziki wasnym obiektom JavaScriptu moesz zaparzy sobie kaw, ktra zrobi dokadnie
to, co bdziesz chcia a wszystko to dziki korzyciom, jakie zapewniaj waciwoci i metody.
W efekcie powstaje obiektowy, nadajcy si do wielokrotnego stosowania kod, ktry rozszerza
moliwoci jzyka JavaScript tylko i wycznie dla Ciebie!

Blog
toString()
Ju mnie gowa
rozbolaa od zabaw
t now kostk... toHTML()

Klasa obiektu

16 sierpnia 2008

Blog

containsText()

Blog

Ponowna analiza metod obiektu Blog

462

Przecianie metod

463

Klasy i instancje

464

Instancje s tworzone na podstawie klasy

465

Sowo kluczowe this zapewnia dostp do waciwoci obiektw

466

Nale do jednej, dziaaj we wszystkich metody nalece do klasy

467

Korzystaj z prototypu, by operowa na poziomie klasy

468

Klasy, prototypy i MagicznaKostka

469

Take waciwoci klasowe s wspdzielone

474

Tworzenie waciwoci klasowych przy uyciu prototypu

475

Podpisane i dostarczone

477

Metoda formatujca daty

480

Rozszerzanie standardowych obiektw

481

Zmodyfikowany obiekt daty = lepsza strona Reni

482

Klasa moe mie swoj wasn metod

483

Analiza funkcji porwnujcej wpisy

485

Wywoywanie metody klasowej

486

Jeden obraz jest wart tysica sw w blogu

487

Dodawanie obrazkw do blogu

488

Dodawanie obrazkw do strony MagicznaKostka

490

Obiektowa strona blogu

492

toString()
Znalazam
w internecie
ukadank 777. toHTML()
O rany! Zabawa
bdzie...
21 sierpnia 2008

Blog

containsText()
toString()

Spotkaam si
z kilkoma innymi
toHTML()
zapalecami,
by porozmawia
o ukadaniu...
29 sierpnia 2008

containsText()

15

Spis treci

Zabijaj pluskwy na mier!

11

Dobre skrypty na zej drodze


Nawet najlepiej zaplanowany kod JavaScript moe czasami zawie. Kiedy tak
si stanie, a kiedy na pewno to nastpi, to Twoim zadaniem bdzie opanowa nerwy i nie wpada
w panik. Najlepsi programici to nie tacy, ktrzy nigdy nie popeniaj bdw tacy s raczej
kamcami. Najlepsi programici to tacy, ktrzy potrafi wytropi pluskwy i pozby si bdw,
ktre sami popenili. Co waniejsze, najlepsi pogromcy pluskiew rozwijaj dobre praktyki
kodowania, ktre minimalizuj niebezpieczestwo popeniania najbardziej zoliwych i trudnych
do wytropienia bdw. Z drugiej strony troch prewencji nie zaszkodzi. Pamitaj, e pluskwy
pojawiaj si zawsze, bdziesz zatem potrzebowa arsenau, by z nimi walczy
Debugowanie w praktyce

16

496

Przypadek wadliwego kalkulatora IQ

497

Wyprbuj kod w rnych przegldarkach

498

Proste sposoby usuwania bdw

501

Dzikie niezdefiniowane zmienne

505

Przetwarzajc wartoci IQ

507

Przypadek bdw w poczeniach z radiem

508

Otwieranie dochodzenia

509

Problem weryfikacji bdw skadniowych (pluskwa nr 1)

510

Uwaga na te acuchy znakw

511

Cudzysowy, apostrofy i konsekwencja

512

Kiedy apostrof nie jest apostrofem, uyj odwrotnego ukonika

513

Nie tylko zmienne mog by niezdefiniowane (pluskwa nr 2)

514

Kady jest zwycizc (pluskwa nr 3)

516

Testowanie przy uyciu okienka dialogowego

517

Obserwowanie zmiennych przy uyciu okienek dialogowych

518

Za logika moe by przyczyn bdw

520

Nikt nie wygrywa! (pluskwa nr 4)

524

Przytoczony iloci denerwujcych okienek dialogowych

525

Tworzymy wasn konsol do testowania skryptw

527

Bdy najgorsze ze wszystkich: bdy czasu wykonywania programu

534

Bestiariusz JavaScriptu

535

Komentarze jako chwilowe wyczniki kodu

538

Niebezpieczestwa zwizane ze zmiennymi-cieniami

540

Spis treci

Dynamiczne dane

12

Szybkie i wraliwe aplikacje internetowe


W nowoczesnym internecie bardzo due znaczenie ma szybko i trafno
reakcji powszechnie oczekuje si, e strony bd byskawicznie reagowa
na kad zachciank uytkownika. Albo przynajmniej marz o tym niektrzy
uytkownicy i twrcy aplikacji internetowych. Wan rol w realizacji tego marzenia odgrywa jzyk
JavaScript, stanowicy kluczowy element technologii o nazwie Ajax, zapewniajcej moliwo
dynamicznego modyfikowania zawartoci i wygldu stron WWW. Dziki Ajaksowi strony WWW
w znacznie wikszym stopniu przypominaj standardowe aplikacje komputerowe, gdy mog
szybko i dynamicznie pobiera oraz zapisywa dane, byskawicznie odpowiadajc na
poczynania uytkownika i to bez przeadowywania stron.
Podajc dynamicznych danych

<html>
<head>
...
</head>
<body>
...
</body>
</html>

youcube.html

<blog>
<title>...
<author>...
<entries>
<entry>
...
</entry>
...
</entries>
</blog>

blog.xml

546

MagicznaKostka sterowana danymi

547

Ajax oznacza komunikacj

549

XML pozwala nam opisywa nasze dane po swojemu

550

XML + HTML = XHTML

553

XML i dane blogu Reni

555

Ajax wzmacnia stron MagicznaKostka

558

XMLHttpRequest JavaScript spieszy z pomoc

560

GET czy POST? Uycie obiektu XMLHttpRequest

563

Aby zrozumie ajaksowe dania

567

Interaktywne strony zaczynaj si od obiektu dania

571

Zawoaj mnie, kiedy skoczysz

572

Obsuga dania bezproblemowa

573

DOM spieszy z pomoc

574

Teraz strona MagicznaKostka jest w peni zalena od swoich danych

579

Niedziaajce przyciski

581

Przyciski potrzebuj danych

582

Usprawnienia oszczdzajce czas blogera

585

Zapisywanie danych blogu

586

Take PHP ma swoje potrzeby

588

Przekazywanie danych do skryptu PHP

590

Do rzeczy przesyanie danych wpisu na serwer

593

Uatwienie korzystania ze strony blogu

598

W ramach uatwienia automatycznie wypeniaj pola formularzy

599

Wielokrotnie wykonywane zadanie? Moe by tak jaka funkcja pomoga?

600

Skorowidz

605

17

6. Funkcje

Redukuj i uywaj wielokrotnie


Wiesz, co jest
najwaniejsze w klopsach?
To, e przygotowujesz je
raz, a potem moesz je
tygodniami Ratunku, niech
mi kto pomoe!

Gdyby w wiecie JavaScriptu zaistnia jaki ruch rodowiskowy, to zapewne


na jego czele stanyby funkcje. Funkcje pozwalaj na pisanie bardziej efektywnego kodu
i sprawiaj, e atwiej mona go wielokrotnie uywa. Funkcje s zorientowane na wykonywanie
konkretnych zada i znaczco uatwiaj organizacj kodu. Wyglda to jak cakiem dobry yciorys!
W praktyce niemal wszystkie skrypty, moe za wyjtkiem tych najprostszych, mog skorzysta na
reorganizacji kodu i zastosowaniu funkcji. Cho trudno jest oceni znaczenie i wpyw przecitnej
funkcji, to jednak naley zaznaczy, e odgrywaj one znaczc rol w staraniach, by skrypty byy
moliwie jak najbardziej przyjazne dla rodowiska.

to jest nowy rozdzia  263

Podzia duych problemw

Matka wszystkich problemw


Skoro ju o tym wspomnielimy, to warto zauway, e tworzenie skryptw na
stronach WWW ma na celu rozwizywanie problemw. Niezalenie od tego, jak duy
i skomplikowany jest problem, jeli zostanie on odpowiednio przemylany, to zawsze
znajdzie si rozwizanie. No ale co z naprawd wielkimi problemami?

Pokj na wiecie
To jest naprawd
wielki problem!

Caa sztuczka z rozwizywaniem duych problemw polega na podzieleniu ich


na mniejsze, ktre bdzie mona atwiej rozwiza. A jeli i te problemy s zbyt
due, to i je naley podzieli.

Duy problem.

Mniejszy problem.

Poywienie

Uprawa

Dystrybucja

Prawa
obywatelskie

Schronienie

Prawa
do gruntw

Budownictwo

Wolno
wypowiedzi

Jeszcze mniejsz
y
problem.

Prawo do
gosowania

Kontynuuj ten proces dalej i dalej, i dalej

264

Rozdzia 6.

Funkcje

Rozwizuj due problemy poprzez rozwizywanie


problemw mniejszych
Kontynuujc dzielenie problemu pokoju na wiecie na coraz to mniejsze problemy, dojdziesz
w kocu do problemu na tyle maego, e mona go rozwiza, wykorzystujc JavaScript.

Schronienie

Dobry problem, ktry


w sam raz nadaje
si do rozwizania
w JavaScripcie.

Budownictwo

Materiay

Narzdzia

Klimatyzacja

Sprbuj wymyli JavaScriptowy odpowiednik problemu sterowania klimatyzacj,


ktry wywoywaby skryptowy odpowiednik klimatyzatora, aby ten regulowa
temperatur otoczenia. Najprostsze urzdzenie do sterowania klimatyzacj, jakie
mona sobie wyobrazi, skadaoby si wycznie z przycisku Ogrzewanie.

Najprostszy
z moliwych
klimatyzatorw
nacinij przycisk,
a urzdzenie zrobi,
co trzeba.

Nie obchodzi nas,


w jaki sposb
urzdzenie reguluje
temperatur
wystarczy, e
bdziemy wiedzie,
jak mona je
wczy.

Zauwa, e urzdzenie nie zdradza adnej informacji, ktra mogaby nam


powiedzie, w jaki sposb reguluje si temperatur otoczenia. Wystarczy, e
naciniemy przycisk, a wszystko zostanie zrobione za nas. Ot i tak oto problem
klimatyzacji zosta rozwizany!

jeste tutaj  265

Funkcje narzdzia do rozwizywania niewielkich problemw

Funkcje jako narzdzia do rozwizywania problemw


Przycisk Ogrzewanie sucy do wczania klimatyzacji jest odpowiednikiem funkcji
w jzyku JavaScript. Cay pomys jest bardzo podobny do dziaania rzeczywistej
klimatyzacji kto da wczenia ogrzewania w domu, a funkcja mu to zapewnia.
Szczegy procesu ogrzewania s ukryte wewntrz funkcji i nie maj najmniejszego
znaczenia dla kodu, ktry j wywouje. Pod tym wzgldem mona wyobrazi sobie
funkcj jako pewnego rodzaju czarn skrzynk informacje mog do niej wpywa
i wypywa, jednak to, co si dzieje wewntrz, zaley wycznie od skrzynki i dlatego nie
ma znaczenia dla kodu umieszczonego poza ni.

damy ogrzewania

Funkcje
przeksztacaj
due problemy
w mniejsze.

Temperatura si podnosi

Stworzenie odpowiednika przycisku Ogrzewanie w kodzie JavaScript wymagaoby


wywoania funkcji o nazwie heat()...

heat();

damy ogrzewania

function heat() {

Temperatura si podnosi
Kady, kto chce wczy
ogrzewanie, musi wiedzie,
jak wywoa funkcj heat().

// W jaki sposb zaczynamy ogrzewa


shovelCoal();
lightFire();
harnessSun();
}

Jedyn osob, ktra musi


przejmowa si faktycznym
sposobem ogrzewania, jest
twrca funkcji heat().

266

Rozdzia 6.

Samo ogrzewanie jest


realizowane poprzez wywoanie
trzech kolejnych funkcji.

Sposb, w jaki funkcja heat() wykonuje proces ogrzewania, nie ma


kluczowego znaczenia. Najbardziej liczy si to, e funkcja ta stanowi
niezalene rozwizanie problemu ogrzewania. Jeli jest Ci zimno
i chcesz nieco podnie temperatur w domu, wystarczy wywoa
t funkcj. Szczegowy sposb rozwizania problemu ogrzewania
pozostaje sodk tajemnic funkcji.

Funkcje

Tworzenie funkcji w praktyce


Kiedy podejmiesz decyzj napisania funkcji, automatycznie staniesz si autorem
rozwizania pewnego problemu. Stworzenie funkcji wymaga zastosowania
spjnej skadni, wicej jej nazw z kodem, ktry dana funkcja ma wykonywa.
W najprostszej wersji skadnia funkcji ma nastpujc posta:

function

trz
Kod umieszczony wewn d
raw
nap
tak
t
jes
i
funkcj
onej,
czci instrukcji zo
rozpoczynajcej si tym
nawiasem klamrowym.

To jest identyfikator
zapisany wedug zasad
notacji lowerCamelCase.

Zaczynamy funkcj
od sowa kluczowego
function.

Nazwa

()

Ciao funkcji

Tu koczymy funkcj,
umieszczajc zamykajcy
nawias klamrowy.

Ciao funkcji to miejsce,


w ktrym wykonywane s
wszystkie operacje.

Nawiasy wskazuj,
e mamy do
czynienia z funkcj.

Zapoznanie si z kodem umieszczonym wewntrz funkcji heat()


pozwala spojrze na skadni funkcji z nieco innej perspektywy:

function heat() {
// W jaki sposb zaczynamy ogrzewa
Tak naprawd
ogrzewanie jest
realizowane
wewntrz funkcji.

shovelCoal();
lightFire();
harnessSun();
}

Ciao funkcji jest zapisane


wewntrz nawiasw klamrowych
czyli w rzeczywistoci jest
to doskonale nam ju znana
instrukcja zoona.

WYT
UMYS

Gdzie we wczeniejszej czci ksiki do rozwizywania problemw wykorzystalimy funkcje?

jeste tutaj  267

Funkcje w aplikacji Mandango

Funkcje, ktre ju poznae


Jeli chcesz znale doskonae przykady funkcji sucych do rozwizywania konkretnych
problemw, 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).
Przykadem tym jest funkcja suca do inicjalizacji danych dotyczcych dostpnoci miejsc.

Wyszukiwanie
miejsc dla macho

Inicjalizacja
miejsc

Wyszukiwanie
miejsc

Duy problem

Mniejsze problemy

Podproblem polegajcy na inicjalizacji miejsc by na tyle may, e udao si go


nam rozwiza i zaimplementowa w postaci funkcji, a konkretnie rzecz biorc:
funkcji initSeats():
function initSeats() {
// Inicjalizacja wygldu wszystkich miejsc
for (var i = 0; i < seats.length; i++) {
for (var j = 0; j < seats[i].length; j++) {
if (seats[i][j]) {
// Okrelamy dostpne miejsce
document.getElementById("seat" + (i * seats[i].length
document.getElementById("seat" + (i * seats[i].length
}
else {
// Okrelamy zajte (niedostpne) miejsce
document.getElementById("seat" + (i * seats[i].length
document.getElementById("seat" + (i * seats[i].length
}
}
}
}

Funkcja initSeats() jest jednym z elementw aplikacji Mandango. Funkcja


ta jest wywoywana dopiero w procedurze obsugi zdarze onload; a zatem
zostanie ona wykonana dopiero po wczytaniu caej strony.
<body onload="initSeats();">
align:center">
<div style="margin-top:25px; text<img id="seat0" src="" alt="" />

+ j)).src = "seat_avail.png";
+ j)).alt = "Miejsce dostpne";

+ j)).src = "seat_unavail.png";
+ j)).alt = "Miejsce zajte";

Funkcja initSeats() nie jest


jedynym narzdziem do
rozwizywania problemw
wykorzystywanym
w aplikacji Mandango.

...
<img id="seat1" src="" alt="" />
/>
<img id="seat35" src="" alt="" /><br
ats();" />
value="Szukaj miejsc" onclick="findSe
<input type="button" id="findseats"
</div>
</body>
</html>

268

Rozdzia 6.

Funkcje

Nie ma

niemdrych pyta

P: Moesz jeszcze raz


przypomnie konwencje uywane
podczas okrelana nazw funkcji?

O: Podczas okrelania nazw

identyfikatorw w JavaScripcie uywana


jest konwencja lowerCamelCase, w myl
ktrej pierwsze sowo identyfikatora
jest zapisywane ma liter, a wszystkie
pozostae wielk. A zatem funkcja
suca do oceniania filmw nosiaby nazw
ocenFilm(), natomiast funkcja usuwajca
z sali kinowej widza, ktry zapomnia
wyczy telefonu komrkowego, mogaby
si nazywa: usunHalasliwegoWidza().

P: Czy funkcje zawsze su do


dzielenia duych problemw na
mniejsze?

O: Niekoniecznie. Czasami przydatne

moe by take zastosowanie funkcji do


dzielenia pracy nad kodem. Innymi sowy,
moe si zdarzy, e jeden problem bdzie
rozwizywany przez kilka wsppracujcych
ze sob funkcji.

W takim przypadku podzia kodu na


funkcje ma nam umoliwi organizacj
pracy i uatwi tworzenie funkcji, z ktrych
kada bdzie mie jedno precyzyjnie
okrelone przeznaczenie. Na podobnej
zasadzie pracownicy s zatrudniani na
stanowiskach o rnych nazwach, by kady
z nich mg si skupi na rozwizywaniu
unikalnych i konkretnych problemw.
Takie funkcje mog, cho nie musz,
rozwizywa konkretne problemy; niemniej
na pewno poprawiaj struktur skryptw,
gdy pozwalaj dzieli ich kod na czci.

jest ani dobrym, ani zalecanym rozwizaniem,


gdy zmusza nas do pielgnacji i ewentualnej
modyfikacji kodu w kilku miejscach skryptu.

P: A skd wiadomo, kiedy

P: Czy nie wspominae o tym,

i jaki fragment kodu naley


zaimplementowa jako funkcj?

O: Niestety, nie ma adnego magicznego

sposobu, ktry pozwalaby okreli, kiedy


warto napisa fragment kodu jako funkcj.
Mona jednak wskaza pewne czynniki,
ktre mona potraktowa jako sygnay
i podpowiedzi dotyczce moliwoci
tworzenia funkcji. Jednym z nich jest sytuacja,
w ktrej pewien fragment kodu bdzie si
powtarza. Powielanie kodu niemal nigdy nie

A zatem taki powtarzajcy si kod


doskonale nadaje si do zaimplementowania
w formie funkcji. Innym sygnaem, na
jaki naley zwraca uwag, s dugie,
trudne do zarzdzania bloki kodu, ktre
w prosty sposb mona podzieli na kilka
logicznych czci. Taki kod to doskonaa
okazja do zastosowania podziau pracy
czyli podzielenia tego kodu na czci
i umieszczenia ich w odrbnych funkcjach.

e funkcje mog akceptowa


argumenty i zwraca wartoci?
Czy o czym zapomniaem?

O: Nie. Bez wtpienia s funkcje,

ktre wymagaj przekazania danych


i jednoczenie zwracaj jakie wyniki. Jak si
okae, wanie taka bdzie funkcja heat(),
ktr poznasz w dalszej czci rozdziau.

Nazwa funkcji ma bardzo due znaczenie, gdy moe przekazywa informacje o jej przeznaczeniu. Sprbuj
wymyli nazwy dla opisanych poniej funkcji, pamitajc przy tym, by w odpowiedni sposb je zapisa.

wiczenie
Popro o fotel
przy przejciu

Popro o zwrot
kosztw

Odbierz bilet.
............................................

Odbierz
przyznane pienidze.
............................................

Wyrzu popcorn

Popcorn zosta rozsypany


na innych widzw.
............................................

jeste tutaj  269

Rozwizanie wiczenia

Nazwa funkcji ma bardzo due znaczenie, gdy moe przekazywa informacje o jej przeznaczeniu. Sprbuj
wymyli nazwy dla opisanych poniej funkcji, pamitajc przy tym, by w odpowiedni sposb je zapisa.

wiczenie
Rozwizanie Popro o fotel
przy przejciu

Popro o zwrot
kosztw

Odbierz bilet.
poprosOMiejscePrzyPrzejsciu()
................................................................

Odbierz
przyznane pienidze.
poprosOZwrot()
.................................................................

Wyrzu popcorn

Popcorn zosta rozsypany


na innych widzw.
wyrzucPopcorn()
................................................................

Z powodzeniem mona by wymyli inne nazwy dla tych funkcji.


W kadym razie s to przykady sensownych nazw zapisanych
zgodnie z zaoeniami notacji lowerCamelCase.

Chyba si ugotuj, niech kto


wyczy ogrzewanie. A moe
to efekt lokalnego ocieplenia
klimatu?

Sss ale
milutko!

Zbyt gorco by cokolwiek zrobi


W midzyczasie okazao si, e prby zapewnienia
pokoju na wiecie poprzez kontrol temperatury
otoczenia zaczynaj przynosi wicej szkd ni poytku.
Wyglda na to, e przycisk Ogrzewanie dziaa a nazbyt
dobrze cho moe to jest problem z funkcj heat(),
do ktrej powinnimy przekazywa wicej informacji?
Niezalenie od przyczyny, co z tym trzeba zrobi.

270

Rozdzia 6.

Funkcje

Lepsza klimatyzacja dziki wikszej iloci danych


Wrmy zatem do naszej klimatyzacji Urzdzenie to nie wie, kiedy naley przerwa
ogrzewanie, gdy nie okrelilimy adnej temperatury docelowej. A zatem nasza
klimatyzacja nie ma wystarczajcej iloci informacji, by efektywnie rozwiza problem.
Oznacza to, e kiedy kto nacinie przycisk Ogrzewanie, klimatyzacja zacznie ogrzewa
i nigdy ju nie przestanie!
Pokrto regulacji temperatury
pozwala uytkownikom okreli
temperatur docelow.

Poprawiony klimatyzator pozwala teraz na okrelenie


temperatury docelowej, stanowicej informacj wejciow,
dziki ktrej mona usprawni proces ogrzewania.

damy
ogrzewania

Temperatura
docelowa

Temperatura docelowa
jest informacj
wejciow przekazywan
do funkcji.

wiczenie

Temperatura
si podnosi

heat(targetTemp);

Napisz kod poprawionej funkcji heat(), ktra pobiera temperatur docelow i dziaa (czyli generuje ciepo)
wycznie wtedy, gdy temperatura zmierzona w danej chwili jest mniejsza od docelowej. Podpowied:
skorzystaj z hipotetycznej funkcji getTemp(), by okreli, jaka jest temperatura w danej chwili.
function heat(targetTemp)

.................................................................................................................................................................
Napisalimy
pierwszy wiersz
kodu, by uatwi
Ci rozwizanie
wiczenia.

.................................................................................................................................................................
.................................................................................................................................................................
.................................................................................................................................................................
.................................................................................................................................................................
.................................................................................................................................................................

jeste tutaj  271

Rozwizanie wiczenia

wiczenie
Rozwizanie

Napisz kod poprawionej funkcji heat(), ktra pobiera temperatur docelow i dziaa (czyli generuje ciepo)
wycznie wtedy, gdy temperatura zmierzona w danej chwili jest mniejsza od docelowej. Podpowied:
skorzystaj z hipotetycznej funkcji getTemp(), by okreli, jaka jest temperatura w danej chwili.
function heat(targetTemp)

.................................................................................................................................................................

Temperatura docelowa
while (getTemp() < targetTemp) {
jest przekazywana do .................................................................................................................................................................
funkcji jako argument
// W jaki sposb zaczynamy ogrzewa
.................................................................................................................................................................
jej wywoania.
Temperatura docelowa
shovelCoal();
jest uywana jako element
Obecnie funkcja
.................................................................................................................................................................
warunku sprawdzanego
generuje ciepo
w ptli while.
wycznie wtedy,
lightFire();
.................................................................................................................................................................
gdy aktualna
temperatura
harnessSun();
.................................................................................................................................................................
jest mniejsza
od temperatury
}
.................................................................................................................................................................
docelowej.

}
.................................................................................................................................................................

Przekazywanie informacji do funkcji


Dane s przekazywane do funkcji przy uyciu tak zwanych argumentw.
Przyjrzyj si jeszcze raz skadni funkcji i zwr szczegln uwag na argumenty
umieszczane pomidzy nawiasami, za nazw tworzonej funkcji:
Wewntrz nawias
w mona
umieci jeden lub
wicej
argumentw.

function

Nazwa

Argumenty

Ciao funkcji

ty
Wewntrz ciaa funkcji argumen
byy
y
gdyb
jak
tak,
ane
uyw
s
i.
zainicjowanymi zmiennymi lokalnym

Nie ma adnego limitu okrelajcego maksymaln liczb argumentw, jakie mona


przekaza do funkcji, jednak ze wzgldw praktycznych warto dooy stara, by nie
byo ich wicej ni dwa lub trzy. Argumentem przekazywanym do funkcji moe by
niemal kada informacja: staa (Math.PI), zmienna (temp), jak rwnie litera (23).

272

Rozdzia 6.

Funkcje

Argumenty funkcji jako dane


Kiedy korzystajc z mechanizmu argumentw, przekazujemy do funkcji
pewne dane, to wewntrz tej funkcji staj si one zainicjowanymi zmiennymi
lokalnymi. Przykadem moe by funkcja heat(), do ktrej przekazujemy
argument okrelajcy temperatur docelow:
Zadana temperatura docelowa jesta
przekazywana do funkcji jako liter
liczbowy.

heat(23);

Wewntrz funkcji heat() do informacji o temperaturze docelowej odwoujemy si


jak do zwyczajnej zainicjowanej zmiennej lokalnej o wartoci 23. Warto t mona
wywietli, wywoujc wewntrz funkcji heat() informacyjne okienko dialogowe:

23

function heat(targetTemp)
{
alert(targetTemp);
}

Wewntrz funkcji heat()


argument wyglda jak kada
inna zmienna lokalna.

23

Kiedy wykonywanie
funkcji si zakoczy,
zmienna targetTemp
zostanie usunita.

targetTe
mp

Cho argumenty funkcji s bardzo podobne do zmiennych lokalnych, to jednak


wszelkie modyfikacje argumentw wprowadzane wewntrz funkcji nie maj
adnego wpywu na jakiekolwiek zmienne poza funkcj. Warto zapamita, e
regua ta nie odnosi si do obiektw przekazywanych do funkcji, jednak tymi
zagadnieniami zajmiemy si bardziej szczegowo w rozdziaach 9. i 10.

var temp = 27;


coolIt(temp);
alert(temp);

Zmienna temp jes


przekazywana do t
argument jej wy funkcji jako
woania.

Odejmujemy 1 od
aktualnej temperatury.

function coolIt(temperature)
{
temperature--;
}

Pomimo e
argument temp
jest modyfikowany
wewntrz funkcji,
to jednak zmienna
przechowujca
temperatur poza
funkcj pozostaje
niezmieniona.

jeste tutaj  273

Usuwanie powtrze przy uyciu funkcji

Funkcje eliminuj powtarzajcy si kod


Funkcji mona z powodzeniem uywa nie tylko do dzielenia duych problemw na mniejsze,
ktre bdzie mona atwiej rozwiza. Oprcz tego dziki moliwoci uoglniania zada
funkcje doskonale nadaj si do eliminowania wielokrotnie powtarzajcego si kodu. Cho
niejednokrotnie powtarzajcy si kod nie jest dokadnie identyczny we wszystkich miejscach, to
jednak czsto mona go uoglni i stworzy jedn wersj, ktra nastpnie zostanie umieszczona
w funkcji. Nastpnie mona korzysta z tej funkcji, zamiast powiela fragment kodu.
Poniej przedstawilimy trzy rne fragmenty kodu, ktre wykonuj podobne zadania.
Fragmenty te z powodzeniem mona uoglni i zaimplementowa w formie jednej oglnej
funkcji nadajcej si do wielokrotnego zastosowania:

// Bilet na seans popoudniowy


jest taszy o 10%
biletPopoludniowy = biletNormaln
y * (1 0.10);

Wyraenie obliczajce
cen biletu ze znik
jest niepotrzebnie
powtarzane.

// Bilet dla seniorw jest taszy o 15%


biletSeniorski = biletNormalny * (1 0.15 );

zy o 20%
// Bilet dla dzieci jest tas
y * (1 0.20);
biletDzieciecy = biletNormaln

Powysze zadania polegaj na obliczeniu ceny trzech rnych znikowych biletw


do kina. Mona je jednak uoglni do jednego zadania, ktre bdzie oblicza
cen biletu na podstawie dowolnej zniki, okrelonej jako warto procentowa.

Funkcje
potrafi take
zwraca dane.

function cenaZeZnizka(cena, znizkaProcentowa) {


return (cena * (1 (znizkaProcentowa / 100)));
}

Dysponujc funkcj obliczajc ceny biletw ze znik, moemy


zmodyfikowa trzy przedstawione wczeniej zadania, poprawiajc
przy tym ich efektywno:

// Bilet na seans popoudniowy


jest taszy o 10%
biletPopoludniowy = cenaZeZnizka
(biletNormalny, 10);

// Bilet dla seniorw jest taszy o 15%


biletSeniorski = cenaZeZnizka(biletNormalny, 15);

zy o 20%
// Bilet dla dzieci jest tas
etNormalny, 20);
(bil
izka
ZeZn
biletDzieciecy = cena

274

Rozdzia 6.

Funkcje

BD ekspertem do spraw wydajnoci


Poniej przedstawilimy kod funkcji findSeats()
z aplikacji Mandango w caej jego okazaoci.
Korzystajc ze swojej nowej wiedzy
dotyczcej efektywnoci, zakrel
podobne fragmenty kodu, ktre
mona by w uoglnionej postaci
zaimplementowa jako funkcj.

function findSeats() {
// Jeli jakie miejsce ju zostao wybrane, to ponownie inicjujemy
// wszystkie miejsca, by anulowa wczeniejszy wybr.
if (selSeat >= 0) {
selSeat = -1;
initSeats();
}
// Przegldamy wszystkie miejsca, poszukujc dostpnych
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 nastpne s dostpne
if (seats[i][j] && seats[i][j + 1] && seats[i][j + 2]) {
// Ustawiamy wybr i aktualizujemy wygld 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 uytkownika o zaakceptowanie wyboru miejsca
var accept = confirm("Miejsca od " + (j + 1) + " do " + (j + 3) +
" w rzdzie " + (i + 1) + " s wolne. Wybra je?);
if (accept) {
// Uytkownik zaakceptowa miejsce koczymy (wychodzimy z wewntrznej ptli)
finished = true;
break;
}
else {
// Uytkownik odrzuci wybr, zatem anulujemy wybr 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 dostpne;
document.getElementById("seat + (i * seats[i].length + j + 1)).src = "seat_avail.png;
document.getElementById("seat + (i * seats[i].length + j + 1)).alt = "Miejsce dostpne;
document.getElementById("seat + (i * seats[i].length + j + 2)).src = "seat_avail.png;
document.getElementById(seat + (i * seats[i].length + j + 2)).alt = Miejsce dostpne;
}
}
}
// Inkrementujemy licznik zewntrznej ptli
i++;
}
}

jeste tutaj  275

Rozwizanie wiczenia

BD ekspertem do spraw wydajnoci


Poniej przedstawilimy kod funkcji findSeats()
z aplikacji Mandango w caej jego okazaoci.
Korzystajc ze swojej nowej wiedzy
dotyczcej efektywnoci, zakrel
podobne fragmenty kodu, ktre
mona by w uoglnionej postaci
zaimplementowa jako funkcj.

function findSeats() {
// Jeli jakie miejsce ju zostao wybrane, to ponownie inicjujemy
// wszystkie miejsca, by anulowa wczeniejszy wybr.
if (selSeat >= 0) {
selSeat = -1;
initSeats();
}
// Przegldamy wszystkie miejsca, poszukujc dostpnych
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 nastpne s dostpne
if (seats[i][j] && seats[i][j + 1] && seats[i][j + 2]) {
// Ustawiamy wybr i aktualizujemy wygld 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 uytkownika o zaakceptowanie wyboru miejsca


Poniewa kady
var accept = confirm("Miejsca od " + (j + 1) + " do " + (j + 3) +
z tych szeciu
" w rzdzie " + (i + 1) + " s wolne. Wybra je?);
fragmentw kodu
if (accept) {
wykonuje dokadnie
// Uytkownik zaakceptowa miejsce koczymy (wychodzimy z wewntrznej ptli)
to samo zadanie,
finished = true;
zatem mona je
break;
zamieni w jedn
}
funkcj.
else {
// Uytkownik odrzuci wybr, zatem anulujemy wybr 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 dostpne;
document.getElementById("seat + (i * seats[i].length + j + 1)).src = "seat_avail.png;
document.getElementById("seat + (i * seats[i].length + j + 1)).alt = "Miejsce dostpne;
document.getElementById("seat + (i * seats[i].length + j + 2)).src = "seat_avail.png;
document.getElementById(seat + (i * seats[i].length + j + 2)).alt = Miejsce dostpne;
}
Te

}
// Inkrementujemy licznik zewntrznej ptli
i++;
}
}

276

Rozdzia 6.

Waciwo length wci jest uywana


do okrelania liczby elementw
w tablicy wewntrznej.

fragmenty kodu
powtarzaj si.
Moemy w nich
wyrni pewne
atrybuty

Funkcje

Tworzenie funkcji okrelajcej status miejsc


Teraz, gdy autorzy aplikacji Mandango zobaczyli, co oznacza poprawianie efektywnoci,
a pal si do dodawania nowych funkcji, dziki ktrym ich kod mgby by jeszcze bardziej
wydajny (kody wszystkich przykadw prezentowanych w ksice znajdziesz na serwerze FTP
wydawnictwa Helion, ftp://ftp.helion.pl/przyklady/hfjsc.zip). Jednak, by mc napisa funkcj
setSeat(), Szymek i Jasiek musz najpierw okreli, jakie argumenty bd konieczne
do jej dziaania. Argumenty te mona poda, analizujc powtarzajce si fragmenty kodu
i wskazujc dane, ktre w kadym z nich maj inne wartoci. Analiza powtarzajcych si
fragmentw funkcji findSeats(), pozwala wyrni nastpujce argumenty:

Numer miejsca

status bdzie
Numer miejsca, ktrego
nak indeks
ustawiany. Nie jest to jed
y od lewej do
tabeli, lecz numer liczon
zynajc od 0.
prawej i z gry w d, zac

Atrybuty funkcji
findSeats() zostay
wskazane poprzez
analiz powtarzajcego
si kodu, ktry
niebawem umiecimy
w nowej funkcji.

Chopie, funkcje
rzdz! Musimy ich
mie jak najwicej.

Wiem, ale pozwl,


e oddzwoni za
chwil mam kogo na
drugiej linii.

Status
Status miejsca. Moe on przyjmowa
wartoci: dostpne, zajte, wybrane.
Na jego podstawie okrelany jest
wywietlany na stronie obrazek miejsca.

Opis
e
Opis aktualnego statusu miejsca. Mo
, Miejsce
pne
dost
przyjmowa wartoci: Miejsce
lania
okre
do
y
zajte oraz Twoje miejsce. Su
zka
obra
entu
wartoci atrybutu alt elem
reprezentujcego dane miejsce.

Zaostrz owek
Napisz kod funkcji setSeat() dla aplikacji Mandango.
................................................................................................................................................
................................................................................................................................................
................................................................................................................................................
................................................................................................................................................

jeste tutaj  277

Wielokrotne stosowanie kodu

Zaostrz owek
Napisz kod funkcji setSeat() dla aplikacji Mandango.
Konkretne dane
zastosowane
w oryginalnym
kodzie zostay teraz
zastpione oglnymi
argumentami.

Poszczeglne argumenty zostay


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 dziki zastosowaniu funkcji


Umieszczenie powtarzajcego si kodu w funkcji setSeat() w znaczcy sposb uprocio kod funkcji
findSeats(). Obecnie w kodzie funkcji findSeats() zostao umieszczonych a sze wywoa funkcji
setSeat(), co stanowi znaczc popraw, jeli chodzi o powtarzanie i wielokrotne stosowanie kodu.
Numer miejsca, status
function findSeats() {
oraz opis s przekazywane
...
ch
w kadym wywoaniu
// Przegldamy wszystkie miejsca, poszukujc dostpny
funkcji setSeat().
var i = 0, finished = false;
while (i < seats.length && !finished) {
for (var j = 0; j < seats[i].length; j++) {
s dostpne
// Sprawdzamy, czy aktualnie analizowane miejsce i dwa nastpne
if (seats[i][j] && seats[i][j + 1] && seats[i][j + 2]) {
// Ustawiamy wybr i aktualizujemy wygld 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"

Nasza nowa
funkcja setSeat()
jest wywoywana
w szeciu miejscach.

// Prosimy uytkownika o zaakceptowanie wyboru miejsca


(j + 3) +
var accept = confirm("Miejsca od " + (j + 1) + " do " +
je?");
Wybra
wolne.
s
"
+
1)
+
(i
+
"
" w rzdzie
if (accept) {
z wewntrznej ptli)
// Uytkownik zaakceptowa miejsce koczymy (wychodzimy
finished = true;
break;
}
else {
dalej
// Uytkownik odrzuci wybr, zatem anulujemy wybr i szukamy
selSeat = -1;
");
setSeat(i * seats[i].length + j, "avail", "Miejsce dostpne
");
setSeat(i * seats[i].length + j + 1, "avail", "Miejsce dostpne
");
dostpne
"Miejsce
"avail",
2,
+
j
+
.length
seats[i]
*
i
setSeat(
}

278

Rozdzia 6.

// Inkrementujemy licznik zewntrznej ptli


i++;

Funkcje

Funkcja setSeat() jeszcze bardziej poprawia kod aplikacji Mandango


Jednak nie tylko funkcja findSeats() skorzystaa na zaimplementowaniu naszej nowej funkcji setSeat(). Poprawiona
zostaa take efektywno dziaania funkcji initSeats(), gdy take w niej znajdowa si kod okrelajcy status miejsc.

function initSeats() {
// Inicjalizacja wygldu wszystkich miejsc
for (var i = 0; i < seats.length; i++) {
for (var j = 0; j < seats[i].length; j++) {
if (seats[i][j]) {
Dwa cakiem
// Okrelamy dostpne miejsce
= "seat_avail.png";
zoone wiersze
document.getElementById("seat" + (i * seats[i].length + j)).src
= "Miejsce dostpne";
kodu zostay
document.getElementById("seat" + (i * seats[i].length + j)).alt
zastpione
}
jednym
else {
stosunkowo
// Okrelamy zajte (niedostpne) miejsce
prostym
= "seat_unavail.png";
document.getElementById("seat" + (i * seats[i].length + j)).src
wywoaniem
;
zajte"
e
"Miejsc
=
j)).alt
+
h
].lengt
seats[i
*
document.getElementById("seat" + (i
funkcji.
}
function initSeats() {
}
// Inicjalizacja wygldu wszystkich miejsc
}
for (var i = 0; i < seats.length; i++) {
}
for (var j = 0; j < seats[i].length; j++) {
if (seats[i][j]) {
// Okrelamy dostpne miejsce
setSeat(i * seats[i].length + j, "avail", "Miejsce dostpn
e");
}
Poprzez uoglnienie operacji
sca
miej
usu
else
stat
{
okrelenia
// Okrelamy zajte (niedostpne) miejsce
funkcja setSeat() doskonale
si spisuje w bardzo rnych
setSeat(i * seats[i].length + j, "unavail", "Miejsce zajte"
);
sytuacjach
}
}
}
}

Jak zatem wida, stosunkowo prosta funkcja skadajca si z dwch wierszy kodu jest obecnie
wywoywana a w omiu miejscach kodu aplikacji Mandango. Nie tylko upraszcza to kod skryptu,
lecz take znacznie uatwia jego utrzymanie, gdy gdyby w przyszoci musia zmodyfikowa sposb
zmiany statusu miejsc, wystarczy zmieni go raz w kodzie funkcji setSeat() a nie w omiu
rnych miejscach caego skryptu. aden programista o zdrowych zmysach nie chciaby zmienia
kodu w omiu miejscach, jeli mgby tego unikn. atwo utrzymania fajna rzecz.

KLUCZOWE ZAGADNIENIA
Funkcje pozwalaj nam dzieli due problemy na mae,
dziki czemu mona je atwiej rozwiza.
Funkcje zapewniaj mechanizmy pozwalajce wydziela
zadania i implementowa je w postaci niezalenych
fragmentw kodu nadajcych si do wielokrotnego
stosowania.

Funkcje s doskonaym sposobem eliminacji


powtarzajcego si kodu, gdy kod umieszczony
wewntrz nich moe by uywany dowolnie wiele razy.
Argumenty pozwalaj przekazywa do funkcji informacje
stanowice dane wejciowe dla realizowanego przez ni
zadania.

jeste tutaj  279

Kto pyta, nie bdzi

Nie ma

niemdrych pyta

P: Czy istnieje jakie

P: Dowiedziaem si, e funkcje

P: Jeszcze raz spytam: czy funkcje

ograniczenie liczby argumentw


przekazywanych do funkcji?

zamieniaj due problemy na


mae, pozwalaj dzieli prac
nad skryptem i eliminowa
powtarzajcy si kod. A co jest
najwaniejsze?

s umieszczane w sekcji nagwka,


czy w treci stron WWW?

: I tak, i nie. Nie za wyjtkiem


wielkoci pamici operacyjnej komputera
nie istnieje adne rzeczywiste ograniczenie
liczby argumentw, jakie mona
przekazywa do funkcji. Jeli jednak
funkcja wymaga tylu argumentw, e
wielko pamici komputera zaczyna by
problemem, to powiniene chyba troch
odpocz i przemyle dokadnie to, co
robisz, gdy liczba argumentw musi by
ogromna. W praktyce ograniczenia liczby
argumentw funkcji s raczej zwizane
z projektowaniem kodu chodzi o to, by
liczba argumentw bya sensowna i aby
stosowanie funkcji nie byo koszmarnie
zoone. Oglnie rzecz biorc, zaleca si,
by liczba argumentw wywoania nie
przekraczaa kilku.

O: Wszystko jest rwnie wane. Funkcje

mog by poyteczne i przydatne pod


wieloma wzgldami, a w wielu przypadkach
dobre funkcje pozwalaj osign wiele
celw. Nic zatem nie stoi na przeszkodzie,
by napisa funkcj, ktra jednoczenie
rozwizuje podproblem, zapewnia podzia
zadania na czci i eliminuje powielanie kodu.
W praktyce s to trzy podstawowe cele,
dla ktrych tworzymy funkcje. Jeli jednak
musisz si skoncentrowa na jednym aspekcie
funkcji, to zapewne bdzie to podzia pracy,
ktry w praktyce oznacza, e kada funkcja
ma jedno cile okrelone przeznaczenie. Jeli
kada funkcja bdzie si koncentrowa na
rozwizaniu jednego zadania, to Twj skrypt
bardzo na tym skorzysta.

Ta
klimatyzacja nie
dziaa najlepiej
chyba zaraz zamarzn!

: Funkcje naley umieszcza wewntrz


znacznikw <script>, w nagwku strony,
bd te w niezalenych plikach JavaScript,
ktre nastpnie zostan zaimportowane
w nagwku strony.

P: Gdybym naprawd chcia,


eby funkcja zmieniaa warto
argumentu, to w jaki sposb mog
to zrobi?

O: Nie ma bezporedniej moliwoci

modyfikowania wartoci argumentw funkcji,


tak by modyfikacje te zostay zauwaone
poza funkcj. Jeli zatem chcesz zmieni
pewn informacj przekazan do funkcji jako
argument jej wywoania, to musisz zwrci t
informacj jako wynik dziaania funkcji. Czytaj
dalej, a dowiesz si, jak to zrobi!

Ale
wspaniale
si dzi czuj!

Zima w lipcu
informacje zwrotne z funkcji
Cho aplikacja Mandango wiele zyskaa dziki zastosowaniu funkcji,
to jednak na froncie kontroli temperatury otoczenia funkcje nie radz
sobie ju a tak dobrze. Wyglda na to, e klimatyzator, ktrego kod
zosta napisany w JavaScripcie, wci nie dziaa prawidowo, a niektrzy
uytkownicy powoli zamarzaj, marzc o tym, by nacinicie przycisku
Ogrzewanie powodowao cige i nieprzerwane grzanie.

280

Rozdzia 6.

Funkcje

Znaczenie informacji zwrotnych


Dziki zastosowaniu argumentw funkcji nasz klimatyzator w swojej aktualnej postaci
pozwala na ustawienie temperatury, jednak nie podaje aktualnej, cho jest ona dla nas
wana, gdy stanowi punkt odniesienia, wzgldem ktrego nastawiamy temperatur
docelow. Poza tym zdarza si, e rne klimatyzatory podaj rne temperatury
i to nawet jeli znajd si w tym samym miejscu. Wszystko to prowadzi nas do
jednego wniosku konieczne s jakie informacje zwrotne musimy zna aktualn
temperatur, abymy mogli ustawi sensown temperatur docelow.

Wywietlacz Aktualna
temperatura pozwala
uytkownikom zorientowa
si, jaka jest aktualna
temperatura otoczenia,
dziki czemu s oni
w stanie dokadniej okreli
temperatur docelow.

Teraz nasz klimatyzator co pewien czas wywietla aktualn temperatur, pomagajc tym
samym uytkownikom nastawi optymaln temperatur, jak chcieliby uzyska.

dana
temperatura

Aktualna
temperatura

t
Funkcja getTemp() jes
u
cel
w
ana
yw
wywo
odczytania aktualnej
temperatury.

getTemp();

Wywietlana
jest aktualna
temperatura

Aktualna temperatura
jest zwracana jako wynik
dziaania funkcji.

A zatem naprawd bdziemy potrzebowali jakiego sposobu, ktry zapewni


funkcji moliwo zwracania informacji do kodu, ktry t funkcj wywoa.

WYT
UMYS

Jak sdzisz, w jaki sposb mona nakoni funkcj do zwrcenia jakich danych?

jeste tutaj  281

Zwracanie danych

Zwracanie danych z funkcji


Warto wynikowa

Zwracanie danych z funkcji wymaga zastosowania sowa kluczowego return wraz


z umieszczonymi za nim informacjami, ktre chcemy zwrci. Informacje te zostan
przekazane do kodu, ktry wywoa funkcj.
return

Warto

Sowo kluczowe return


oznacza, e funkcja
zwraca warto.

pozwala zwraca
dane z funkcji do

kodu, ktry j
wywoa.

Zwracana warto
moe by dowolna.

Instrukcj return mona umieci w dowolnym miejscu funkcji; musisz jednak


pamita, e jej wykonanie spowoduje natychmiastowe zakoczenie dziaania funkcji.
A zatem instrukcja ta powoduje nie tylko zwrcenie wartoci wynikowej, lecz take
zakoczenie wykonywania funkcji. Na przykad funkcja getTemp() koczy dziaanie,
zwracajc warto aktualnej temperatury otoczenia:

function getTemp() {
// Odczyt i konwersja aktualnej temperatury
Dane odczytywane z czujnika
temperatury s podawane
w dziwacznym formacie, ktry
naley przeksztaci na warto
wyraon w stopniach.

var rawTemp = readSensor();


var actualTemp = convertTemp(rawTemp);
return actualTemp;
}

Aktualna temperatura jest


zwracana przy uyciu instrukcji
return jako wynik wywoania
funkcji.

Jeli jeste uwany, to zapewne pamitasz, e funkcja getTemp() zostaa ju


wczeniej zastosowana w kodzie obsugujcym dziaanie klimatyzatora:

function heat(targetTemp) {
while (getTemp() < targetTemp) {
// W jaki sposb zaczynamy ogrzewa

raca warto,
Funkcja getTemp() zw warunku
ktra jest uywana w ptli
sterujcym dziaaniem
w funkcji heat().

...
}
}
Warto wynikowa funkcji getTemp() zastpuje wywoanie tej funkcji i staje
si elementem warunku logicznego, sprawdzanego w ptli while.

282

Rozdzia 6.

Warto wynikowa
funkcji zastpuje jej
wywoanie.

Funkcje

Wiele szczliwych wartoci wynikowych


Poniewa instrukcja return powoduje natychmiastowe przerwanie wykonywania funkcji,
zatem mona jej uywa nie tylko do zwracania wartoci, lecz take do sterowania
dziaaniem funkcji. Nie jest to jedyne zastosowanie wartoci wynikowych, jednak funkcje
bardzo czsto uywaj ich, by informowa kod wywoujcy o pomylnym zakoczeniu
dziaania bd o zaistniaych problemach. Nasza przykadowa funkcja heat() stwarza
okazj do przedstawienia tego sposobu wykorzystania instrukcji return.
mp?
Czy pamitasz zmienn actualTe
cana
To wanie jej warto jest zwra
().
emp
getT
cj
funk
z
prze

function heat(targetTemp) {
if (getTemp() >= targetTemp)

Nie musimy wcza ogrzewania;


dlatego te zwracamy warto false
i koczymy dziaanie funkcji.

return false;
while (getTemp() < targetTemp) {
// W jaki sposb zaczynamy ogrzewa
...
}
return true;

To wanie kod umieszczony w tym miejscu


odpowiada za ogrzewanie, co z kolei ma
wpyw na temperatur otoczenia, a co za
tym idzie take na warto wynikow,
zwracan przez funkcj getTemp().

Ogrzewanie zakoczone, tym raze


zwracamy warto true, by poin m
formowa
o pomylnym wykonaniu zadania.

Funkcja heat() demonstruje, w jaki sposb logiczna warto wynikowa moe


kontrolowa przebieg dziaania funkcji, a przy okazji informowa o jej pomylnym
bd nieudanym wykonaniu. Wycznie do celw sterowania dziaaniem funkcji
wystarczy uy samej instrukcji return, bez adnej wartoci wynikowej w takim
przypadku instrukcja ta stanowiaby sposb zakoczenia wywoania funkcji. Oto
kolejna wersja funkcji heat(), ktra nie uywa wartoci wynikowych do przekazania
informacji o pomylnym wykonaniu.

function heat(targetTemp) {
if (getTemp() >= targetTemp)

Ta instrukcja return przerywa


dziaanie funkcji, gdy ogrzewanie
nie jest konieczne.

return;
while (getTemp() < targetTemp) {
// W jaki sposb zaczynamy ogrzewa
...
}
}

Funkcja nawet bez pom


instrukcji return koczyocy
si
tam, gdzie powinna.

Instrukcji return
mona uywa do
przerywania dziaania
funkcji nawet bez
podawania wartoci
wynikowej.
jeste tutaj  283

Instrukcja return bez tajemnic

Instrukcja return bez tajemnic


Temat tego wywiadu:

Sekrety specjalisty od koczenia funkcji


Head First: Witaj. Syszaem, e jeste doprawdy
nieobliczalna zdolna do przerwania kadej funkcji
i wyjcia z niej.
Return: To prawda. Umie mnie w dowolnej funkcji,
a ja byskawicznie zakocz jej dziaanie. Co wicej, mog
nawet zabra ze sob jakie dane.
Head First: A dokd si udajesz, koczc funkcj?
Return: No c Nie zapominaj, e kada funkcja jest
wywoywana z jakiego innego miejsca kodu; a zatem
zakoczenie wykonywania funkcji oznacza powrt do
kodu, ktry j wywoa. Podobnie rzecz si ma w przypadku
zwracania wartoci wynikowej jest ona przekazywana do
kodu, ktry wywoa funkcj.
Head First: Ale jak to dziaa?
Return: Najlepiej bdzie, jeli wyobrazisz sobie funkcj
jako wyraenie, ktre zwraca warto. Jeli funkcja nie
zwraca wartoci, to wyraenie nie ma adnego wyniku. Jeli
jednak funkcja zwrci warto, a naprawd wiele z nich to
robi, to warto ta staje si wynikiem wyraenia.
Head First: A zatem, skoro funkcja jest wyraeniem, to czy
mona jej warto wynikow zapisa w jakiej zmiennej?
Return: I tak, i nie. Widzisz, sama funkcja nie jest
wyraeniem jest nim wywoanie funkcji, co nie zmienia
faktu, e moesz, a czasami nawet powiniene umieci
wywoanie funkcji w takim miejscu, by zwrcona przez
nie warto wynikowa zostaa zapisana w zmiennej. To
wanie w tym miejscu na scen wkraczaj wyraenia
w momencie przetwarzania wywoania funkcji jest ono
traktowane jako wyraenie, ktrego wynikiem jest warto
zwrcona przez funkcj.

Head First: Rozumiem. Ale co si dzieje z tym


wyraeniem, kiedy funkcja niczego nie zwraca?
Return: Jeli uyjesz mnie bez podawania adnej wartoci,
to funkcja niczego nie zwrci, a wyraenie bdzie puste.

Head First: A czy to nie bdzie stanowio problemu?

284

Rozdzia 6.

Return: Nie, nie przypuszczam. Powiniene pamita,


e programici zaprztaj sobie gow wykorzystaniem
wartoci wynikowej wycznie wtedy, gdy wiedz, e dana
funkcja moe co zwrci. Jeli funkcja z zaoenia nie ma
zwraca adnych informacji wynikowych, to nie powiniene
przejmowa si jej wartoci wynikow ani stara si jej
uywa.
Head First: No jasne! Wrmy zatem do twoich
umiejtnoci przerywania funkcji. Czy nie sdzisz, e takie
gwatowne przerywanie funkcji, zanim sama dotrze do
swego naturalnego koca, jest ze i niewaciwe?
Return: Ot nie, i zaraz ci wyjani dlaczego. To, e
funkcja ma swj pierwszy i ostatni wiersz, wcale nie
oznacza, e zostaa zaprojektowana w taki sposb, by kady
wiersz jej kodu by zawsze wykonywany. W rzeczywistoci
myl, e funkcja ma swj pocztek i koniec, moe by nawet
niebezpieczna. Naturalny koniec funkcji moe wypada
w rodku jej kodu, jeli tylko jaki zdolny programista mnie
tam umieci.

Head First: Nie rozumiem. Czy chcesz mi powiedzie,


e w niektrych funkcjach naturalne jest to, e pewne
fragmenty kodu nigdy nie zostan wykonane?
Return: Nigdy nie mwi nigdy, mog ci natomiast
zapewni, e w wielu przypadkach dziaanie funkcji moe
przebiega kilkoma rnymi ciekami a ja czsto
pomagam w ich tworzeniu. Oczywicie, moe si take
zdarzy, e funkcja bdzie wykonywana od deski do
deski, czyli od pierwszego do ostatniego wiersza kodu,
i nigdy o mnie nawet nie usyszy albo uyje mnie na kocu
do zwrcenia wartoci wynikowej.

Head First: Hm rozumiem. A zatem dajesz funkcjom


moliwoci i to zarwno jeli chodzi o zwracanie wynikw,
jak i kontrol dziaania.
Return: Brawo, w kocu co ci zaczo wita.
Head First: No tak lepiej pno ni wcale. Dziki za
rozmow i powicony czas.
Return: Nie ma sprawy. Najwyszy czas, by to skoczy!

Funkcje

wiczenie

Wyglda na to, e JavaScript zosta przyapany w samym centrum skandalu klimatyzacyjnego. Osoby
zrzeszone w ugrupowaniu Umiarkowani Krytycy Radykalnego Ocieplenia Powietrza, w skrcie: UKROP,
napisay skrypt goszcy ich ostrzeenie dotyczce lokalnego ocieplenia. Jednak czonkom ZAMIEC-i,
czyli Zrzeszenia Anonimowych Mionikw Inteligentnej Emisji Ciepa zagorzaym przeciwnikom
idei URKOP-u udao si dokona sabotau kodu tego skryptu. Twoim zadaniem jest wskazanie
prawidowych i sabotowanych fragmentw kodu oraz ujawnienie prawdziwych postulatw UKROP-u.

function showClimatMsg() {
return;
alert(constructMessage());
}
function constructMessage() {
var msg = "";
msg += "Globalne "; // "Lokalne "
if (getTemp() > 27)
msg += "ocieplenie ";
else
msg += "ochodzenie ";
if (true)
msg += "nie jest ";
else
msg = "jest ";

t
hmias
Natyc a
w
przer
e
lokaln e!
ni
e
l
ociep

if (getTemp() <= 21)


return msg + "bujd!";
else
return msg + "faktem!";
return "Ja w to nie wierz.";

Mioniczka
UKROP-u.

}
function getTemp() {
// Odczyt i konwersja aktualnej temperatury
var rawTemp = readSensor();
var actualTemp = convertTemp(rawTemp);
return 18;
}

Aktywista ZAMIEC-i.

Klim
och at si
nap adza
raw
d.

jeste tutaj  285

Rozwizanie wiczenia

wiczenie
Rozwizanie

Wyglda na to, e JavaScript zosta przyapany w samym centrum skandalu klimatyzacyjnego. Osoby
zrzeszone w ugrupowaniu Umiarkowani Krytycy Radykalnego Ocieplenia Powietrza, w skrcie: UKROP,
napisay skrypt goszcy ich ostrzeenie dotyczce lokalnego ocieplenia. Jednak czonkom ZAMIEC-i,
czyli Zrzeszenia Anonimowych Mionikw Inteligentnej Emisji Ciepa zagorzaym przeciwnikom
idei URKOP-u udao si dokona sabotau kodu tego skryptu. Twoim zadaniem jest wskazanie
prawidowych i sabotowanych fragmentw kodu oraz ujawnienie prawdziwych postulatw UKROP-u.

Ta instrukcja skutecznie
uniemoliwia wywietlenie
jakiegokolwiek komunikatu.

function showClimatMsg() {
return;
alert(constructMessage());
}
function constructMessage() {
var msg = "";
Ten kod jest
w porzdku,
gdy komunikat
zaley od
aktualnej
temperatury.

msg += "Globalne "; // "Lokalne "


if (getTemp() > 27)
msg += "ocieplenie ";
else
msg += "ochodzenie ";

Tekst, ktry mia


by wywietlany,
zosta umieszczony
w komentarzu, by
nie pojawia si
w ostrzeeniu.

Instrukcja if,
ktrej warunek
jest zawsze
speniony, nie ma
wikszego sensu.

if (true)
msg += "nie jest ";
else
msg = "jest ";
if (getTemp() <= 21)
return msg + "bujd!";
else
return msg + "faktem!";

Instrukcja if/else
skutecznie uniemoliwi
dotarcie do tego miejsca
kodu, a zatem ta
instrukcja return jest
bezcelowa.

return "Ja w to nie wierz.";

Musimy zwrci
faktyczn
temperatur
zmierzon przez
czujnik.

Dzikuj ci,
JavaScripcie!

function getTemp() {
// Odczyt i konwersja aktualnej temperatury
var rawTemp = readSensor();
var actualTemp = convertTemp(rawTemp);
return 18; actualTemp
}

Lokalne ocieplenie jest faktem!

286

Rozdzia 6.

Tutaj robi si
naprawd ciepo.
Pomocy!

Funkcje

Odczyt statusu miejsca


W siedzibie Mandango Szymek i Jasiek maj ju powyej uszu suchania o zmianach
klimatycznych i s gotowi do wprowadzenia pewnych poprawek do swojego skryptu.
Niektrzy uytkownicy zgaszali problemy z rozrnianiem kolorw siedze i chcieliby
mie moliwo kliknicia dowolnego miejsca w celu sprawdzenia jego dostpnoci.
Wyglda na to, e w kodzie aplikacji Mandango powinna pojawi si nowa funkcja.

Cae to
gadanie o temperaturze
i klimacie mocno mnie osabia.
Musz si zaj popraw mojej
aplikacji Mandango!

Miejsca s numerowane od
lewej do prawej i od gry do
dou, zaczynajc od numeru 0.

Numer
danie
miejsca
pobrania
statusu miejsca

Zostaje
zwrcony
status miejsca

Status
miejsca
getSeatStatus(seatNum);

Status miejsca jest


acuchem znakw, ktry
moe przyjmowa takie
wartoci jak: dostpne,
zajte lub Twoje.

Magnesiki z JavaScriptem
W kodzie funkcji getSeatStatus() brakuje kilku wanych elementw, ktre s jej niezbdne
do okrelenia statusu konkretnego miejsca. W pierwszej kolejnoci, funkcja sprawdza,
czy dane miejsce naley do sekwencji trzech, aktualnie wybranych miejsc. Jeli nie naley,
to funkcja sprawdza w tablicy miejsc czy dane miejsce jest dostpne czy nie. Uzupenij
brakujce miejsca kodu magnesikami widocznymi u dou strony.
function getSeatStatus(seatNum) {
if (

!= -1 && (

||

==

== (

+ 1) ||

return "Twoje";
else if (

[Math.floor(

[0].length)][

+ 2)))

== (

[0].length])

return "dostpne";
else
return "zajte";
}

seats

selSeat

seatNum

jeste tutaj  287

Rozwizanie magnetycznego wiczenia

Magnesiki z JavaScriptem
W kodzie funkcji getSeatStatus() brakuje kilku wanych elementw, ktre s jej niezbdne do
okrelenia statusu konkretnego miejsca. W pierwszej kolejnoci, funkcja sprawdza, czy dane
miejsce naley do sekwencji trzech, aktualnie wybranych miejsc. Jeli nie naley, to funkcja
sprawdza w tablicy miejsc czy dane miejsce jest dostpne czy nie. Uzupenij brakujce miejsca
kodu magnesikami widocznymi u dou strony.
Mamy do czynienia z sekwencj trzech
miejsc pooonych obok siebie, zatem
musimy sprawdzi to miejsce i dwa
nastpne.

Kiedy adne miejsce nie jest wybrane,


zmienna globalna selSeat ma warto 1;
ten warunek sprawdzamy w pierwszej
kolejnoci.
function getSeatStatus(seatNum) {
if ( selSeat

!= -1 &&

t ||
selSea...
( seatNum == ........

seatNum
... == (
seatNum == ( selSeat + 1) || ........

selSeat + 2)))

return "Twoje";
else if (

seats

[Math.floor( seatNum /

seats

[0].length)][ seatNum %

seats

[0].length])

return "dostpne";
else
return "zajte";
}

Okrelamy wiersz w tablicy, w jakim naley szuka


informacji o dostpnoci miejsca, dzielc jego
numer przez liczb miejsc w rzdzie i zaokrglajc
uzyskan warto do liczby cakowitej.

Okrelamy kolumn miejsca


poprzez obliczenie reszty
z dzielenia numeru miejsca
przez liczb miejsc
w rzdzie.

W tym miejscu mona by poda na


stae warto 9, jednak w takim
przypadku, gdybymy zmienili liczb
miejsc w rzdzie, skrypt przestaby
dziaa prawidowo.

Prezentacja statusu miejsca


Pobieranie statusu miejsca jest bardzo wygodne, jednak udostpnienie uytkownikom
moliwoci sprawdzania statusu dowolnie wybranego miejsca wymaga narzdzia,
ktre pozwoli nam wywietli status kliknitego miejsca. Kolejna funkcja,
showSeatStatus(), zapewnia proste rozwizanie tego problemu, sprytnie przekazujc
wykonanie najtrudniejszego zadania napisanej wczeniej funkcji getSeatStatus().

function showSeatStatus(seatNum) {
alert(To miejsce jest + getSeatStatus(seatNum) + .);
}

288

Rozdzia 6.

Aby pobra status miejsca, do


funkcji getSeatStatus() musimy
przekaza numer miejsca, ktre
nas interesuje.

czymy acuchy znakw, by utwo


komunikat informujcy o statusie rzy
miejsca.

Funkcje

Moemy poczy funkcj z obrazkiem


Skojarzenie tej funkcji z obrazkiem wywietlanym na stronie Mandango pozwala uytkownikowi
klikn dowolne miejsce, by sprawdzi jego status. W tym celu kady obrazek miejsca
wywietlany na stronie musi mie zdefiniowan procedur obsugi zdarze onclick, w ktrej
bdzie wywoywana funkcja showSeatStatus(). Oto przykad takiej procedury obsugi zdarze:

<im id="seat23" src="" alt="" onclick="showSeatStatus(23);" />

Funkcja
showSeatStatus()
zostanie wywoana,
gdy uytkownik kliknie
obrazek "seat23".

onclick!

Miejsce numer 23.

Jedno kliknicie tyle wystarczy, by wywietli status dowolnego miejsca


w informacyjnym okienku dialogowym. Na moliwoci tej skorzystaj wszyscy,
ktrzy maj trudnoci z rozrnieniem kolorw miejsc prezentowanych na
stronie albo lubi klika i w ten sposb sprawdza statusy miejsc.

KLUCZOWE ZAGADNIENIA
Polecenie return pozwala zwraca dane z funkcji do
kodu, ktry j wywoa.
Kiedy pewna informacja jest zwracana jako wynik
wykonania funkcji, to zastpuje ona jej wywoanie.

Funkcja moe zwrci tylko jedn informacj.


Instrukcja return moe by stosowana bez podawania
adnej danej wynikowej, w takim przypadku po prostu
przerywa jej dziaanie.

jeste tutaj  289

Strukturalne rozszerzenia kodu

Powielanie kodu nigdy nie jest dobre


Skrypt aplikacji Mandango dziaa cakiem dobrze, lecz jego autorzy zaczynaj si
powoli martwi o utrzymanie go w duszej perspektywie. Mwic konkretnie,
Jasiek przeprowadzi pewne badania i dowiedzia si, e nowoczesne aplikacje
internetowe czsto mog wiele zyska na separacji kodu HTML, JavaScript i CSS.

<html>
<head>
itle>
<title>Mandango - Wyszukiwarka miejsc dla prawdziwych mczyzn</t
<script type="text/javascript">
...
function initSeats() {
...
}
function getSeatStatus(seatNum) {
...
}
function showSeatStatus(seatNum) {
alert("To miejsce jest " + getSeatStatus(seatNum) + ".");
}
function setSeat(seatNum, status, description) {
status + ".png";
document.getElementById("seat" + seatNum).src = "seat_" +
;
document.getElementById("seat" + seatNum).alt = description
}
function findSeats() {
...
}
</script>
</head>

Na stronie
aplikacji
Mandango kod
JavaScript
przeplata
si z kodem
HTML.

290

Kod JavaScript i HTML


wystpujcy wsplnie mona
izolowa w atrybutach HTML
obsugujcych zdarzenia.

<body onload="initSeats();">
<div style="margin-top:25px; text-align:center">
/>
<img id="seat0" src="" alt="" onclick="showSeatStatus(0);"
/>
<img id="seat1" src="" alt="" onclick="showSeatStatus(1);"
/>
<img id="seat2" src="" alt="" onclick="showSeatStatus(2);"
/>
s(3);"
owSeatStatu
<img id="seat3" src="" alt="" onclick="sh
/>
s(4);"
owSeatStatu
onclick="sh
alt=""
src=""
id="seat4"
<img
/>
s(5);"
<img id="seat5" src="" alt="" onclick="showSeatStatu
/>
s(6);"
owSeatStatu
onclick="sh
alt=""
src=""
<img id="seat6"
/>
<img id="seat7" src="" alt="" onclick="showSeatStatus(7);"
/><br />
s(8);"
owSeatStatu
onclick="sh
<img id="seat8" src="" alt=""
/>
<img id="seat9" src="" alt="" onclick="showSeatStatus(9);"
/>
s(10);"
owSeatStatu
<img id="seat10" src="" alt="" onclick="sh
/>
s(11);"
owSeatStatu
onclick="sh
alt=""
src=""
id="seat11"
<img
/>
s(12);"
<img id="seat12" src="" alt="" onclick="showSeatStatu
/>
s(13);"
owSeatStatu
onclick="sh
alt=""
<img id="seat13" src=""
/>
<img id="seat14" src="" alt="" onclick="showSeatStatus(14);"
/>
s(15);"
owSeatStatu
onclick="sh
<img id="seat15" src="" alt=""
/>
<img id="seat16" src="" alt="" onclick="showSeatStatus(16);"
/><br />
s(17);"
owSeatStatu
<img id="seat17" src="" alt="" onclick="sh
/>
s(18);"
owSeatStatu
onclick="sh
alt=""
src=""
<img id="seat18"
/>
<img id="seat19" src="" alt="" onclick="showSeatStatus(19);"
/>
s(20);"
owSeatStatu
onclick="sh
alt=""
<img id="seat20" src=""
/>
<img id="seat21" src="" alt="" onclick="showSeatStatus(21);"
/>
s(22);"
owSeatStatu
<img id="seat22" src="" alt="" onclick="sh
/>
<img id="seat23" src="" alt="" onclick="showSeatStatus(23);"
/>
s(24);"
<img id="seat24" src="" alt="" onclick="showSeatStatu
/>
s(25);"
owSeatStatu
onclick="sh
alt=""
src=""
<img id="seat25"
/><br />
<img id="seat26" src="" alt="" onclick="showSeatStatus(26);"
/>
s(27);"
owSeatStatu
onclick="sh
alt=""
<img id="seat27" src=""
/>
<img id="seat28" src="" alt="" onclick="showSeatStatus(28);"
/>
s(29);"
owSeatStatu
<img id="seat29" src="" alt="" onclick="sh
/>
<img id="seat30" src="" alt="" onclick="showSeatStatus(30);"
/>
s(31);"
<img id="seat31" src="" alt="" onclick="showSeatStatu
/>
s(32);"
owSeatStatu
onclick="sh
alt=""
src=""
<img id="seat32"
/>
<img id="seat33" src="" alt="" onclick="showSeatStatus(33);"
/>
s(34);"
owSeatStatu
onclick="sh
alt=""
<img id="seat34" src=""
/><br />
<img id="seat35" src="" alt="" onclick="showSeatStatus(35);"
ndSeats();" />
onclick="fi
miejsc"
aj
value="Szuk
<input type="button" id="findseats"
</div>
</body>
</html>

Rozdzia 6.

Widz tu
wymieszanych
wiele rodzajw
kodu.

Funkcje

Separacja funkcjonalnoci od zawartoci


Ale o co caa ta afera z mieszaniem kodu? Przecie wszystko dziaa bez najmniejszych problemw,
prawda? Problem ten wyglda jednak zupenie inaczej, kiedy spojrzy si na dokumenty HTML
wykorzystujce skrypty JavaScript nie jako zwyczajne strony WWW, lecz jako aplikacje.
A podobnie jak wszystkie aplikacje, take te pisane w jzyku JavaScript wymagaj starannego
zaplanowania i zaprojektowania, zwaszcza jeli zaley nam na tym, by odniosy sukces w duszej
perspektywie. Naley zauway, e dobre aplikacje zawieraj mniej bdw i atwiej je pielgnowa,
kiedy ich zawarto, prezentacja i funkcjonalno s od siebie wyranie oddzielone. A jak wida,
w aktualnej wersji aplikacji Mandango o jakiejkolwiek separacji nie moe by mowy.

Zawarto

<html>
...
</html>

To kod HTML strony, okrelajcy


jej fizyczn struktur oraz
prezentowane na niej treci.

Rozdzielenie zawartoci,
prezentacji i funkcjonalnoci
sprawia, e duy problem
jest rozkadany na kilka
mniejszych.

Funkcjonalno

<script>
...
</script>

Prezentacja

<style>
...
</style>

Na t cz strony skada si uywany


na niej kod CSS, odpowiadajcy za
okrelenie wygldu strony, w tym takich
jego aspektw jak czcionki, kolory,
a nawet ukad treci.

To kod napisany w jzyku JavaScript,


ktry obsuguje dziaanie strony
i zapewnia jej interaktywno. Moesz
go sobie wyobrazi jako t cz stro
ny,
ktra odpowiada za jej dziaanie.

Zagadnienia zwizane z separacj kodu mona wyobrazi sobie w nastpujcy


sposb. Zamy, e Jasiek i Szymek znaleli naprawd wietny skrypt do
zarzdzania miejscami w sali kinowej i chcieliby go zastosowa zamiast wasnego.
W takim przypadku musieliby przebudowa aplikacj w taki sposb, by korzystaa
z kodu nowego skryptu, jednak tym samym naraziliby si na ryzyko uszkodzenia
struktury strony, gdy ich kod JavaScript jest cile zintegrowany z kodem HTML.
Byoby zatem znacznie lepiej, gdyby kod HTML zosta odseparowany, a powizanie
kodu JavaScript i HTML wystpowao wycznie w kodzie JavaScript.

Separacja
funkcjonalnoci od
zawartoci uatwia
tworzenie aplikacji
internetowych oraz ich
pniejsze utrzymanie.

WYT
UMYS

Czy masz jaki pomys na zastosowanie funkcji w celu odseparowania funkcjonalnoci od


zawartoci w aplikacji Mandango?

jeste tutaj  291

Dane = funkcje

Funkcje s zwykymi danymi


Aby mg efektywnie rozdzieli kod, musisz najpierw zrozumie, w jaki sposb
funkcje s powizane ze zdarzeniami. Do tej pory kojarzenie to byo realizowane
przy uyciu atrybutw HTML. Istnieje jednak inny sposb, ktry przez wiele
osb jest uwaany za znacznie lepszy od mieszania kodu HTML i JavaScript.
Jednak zastosowanie go wymaga zupenie innego spojrzenia na funkcje.
Cho to zaskakujce, jednak w rzeczywistoci funkcje s zwyczajnymi
danymi. Tak, to prawda. Caa tajemnica polega na tym, e ciao funkcji jest
wartoci, a jej nazwa zmienn. Poniej przedstawilimy sposb prezentacji
funkcji, ktry znasz i do ktrego jeste przyzwyczajony:

Ta funkcja jest tworzona w doskonale


znany, standardowy sposb.

function showSeatStatus(seatNum) {
alert("To miejsce jest " + getSeatStatus(seatNum) + ".");
}
Ten kod dziaa bardzo dobrze, jednak t sam funkcj
mona utworzy take w inny sposb:

var showSeatStatus

Nazw funkcji jest w tym


przypadku nazwa zmiennej.

= function(seatNum) {

alert("To miejsce jest " + getSeatStatus(seatNum) + ".");


} ;

Wartoci zmiennej jest ciao funk


ktre jeli zostanie wyraone wa cji,
w taki sposb, jest take okrelan nie
e
jako litera funkcyjny.

Powyszy przykad pokazuje, w jaki sposb mona utworzy funkcj,


wykorzystujc przy tym skadni charakterystyczn dla okrelania wartoci
zmiennych. Jak wida, uywane s przy tym nawet te same elementy kodu:
unikalny identyfikator (nazwa funkcji) oraz warto (ciao funkcji). Kiedy ciao
funkcji wystpuje samo, bez nazwy funkcji, nazywane jest literaem funkcyjnym.
Ta niesamowita informacja dotyczca funkcji jest tak interesujca, gdy
pokazuje, e funkcjami mona posugiwa si podobnie jak zmiennymi.
Jak sdzisz, co robi przedstawiony poniej fragment kodu?

var myShowSeatStatus = showSeatStatus;


Zapisuje funkcj
showSeatStatus() w zmiennej
myShowSeatStatus.

292

Rozdzia 6.

Funkcje

Wywoania i odwoania do funkcji


Kiedy przypiszesz nazw funkcji do innej zmiennej, udzielisz jej dostpu do ciaa tej
funkcji. Innymi sowy, bdziesz mg wywoa t funkcj, tak jak to pokazalimy na
poniszym przykadzie:

alert(myShowSeatStatus(23));

Wywoanie tej samej funkcji


showSeatStatus() przy uyciu
zmiennej myShowSeatStatus.

Kocowy efekty wywoania myShowSeatStatus() jest identyczny jak wywoania


showSeatStatus(), gdy w rzeczywistoci obie funkcje odwouj si do tego samego
kodu. Wanie z tego powodu nazwa funkcji jest take nazywana odwoaniem lub
referencj do funkcji.

showSeatStatus

function() {
...

myShowSeatStatus

Rozrnienie pomidzy odwoywaniem si do funkcji a jej wywoywaniem odbywa


si na podstawie pary nawiasw (()) umieszczanych za jej nazw. W przypadku
odwoywania si do funkcji nawiasy te nie wystpuj, natomiast w przypadku
wywoywania s obowizkowe. Co wicej, w przypadku wywoywania funkcji
w nawiasach czsto pojawiaj si dodatkowe argumenty.
Wywoanie funkcji
myShowSeatStatus(), ktre
w efekcie jest dokadnie tym
samym co wywoanie funkcji
showSeatStatus().

Tak naprawd
funkcja jest
jedynie zmienn,
ktrej wartoci
jest odwoanie
do ciaa funkcji.

var myShowSeatStatus = showSeatStatus;


myShowSeatStatus(23);

Zapisanie w zmiennej
myShowSeatStatus odwoania
do funkcji.

Przeanalizuj przedstawiony poniej fragment kodu i zapisz liczb, ktra zostanie wywietlona w okienku dialogowym.

wiczenie

function doThis(num) {
return num++;
}
function doThat(num) {
return num--;
}
var x = doThis(11);
var y = doThat;
var z = doThat(x);
x = y(z);
y = x;
alert(doThat(z y));

jeste tutaj  293

Rozwizanie wiczenia

Przeanalizuj przedstawiony poniej fragment kodu i zapisz liczb, ktra zostanie wywietlona w okienku dialogowym.

wiczenie
Rozwizanie

function doThis(num) {
return num++;
}
function doThat(num) {
return num--;
}
var x = doThis(11);
var y = doThat;
var z = doThat(x);
x = y(z);
y = x;
alert(doThat(z y));

x = 12
y = doThat
z = doThat(12) = 11
x = doThat(11) = 10
y = 10
alert(doThat(11 10))

Nie ma

niemdrych pyta

P: Czy separacja zawartoci jest


naprawd tak wana, by trzeba
byo zaprzta sobie ni gow?

O: I tak, i nie. W przypadku


niewielkich aplikacji umieszczanie
w jednym pliku kodu HTML,
JavaScript i CSS nie jest niczym
niewaciwym. Znaczenie i korzyci,
jakie zapewnia separacja kodu, mona
znacznie atwiej zauway dopiero
w wikszych aplikacjach, w ktrych
tego kodu jest bardzo duo. W takich
duych aplikacjach znacznie trudniej
jest wypracowa sobie bardziej oglne
pojcie o dziaaniu kodu, zwaszcza
gdy rne rodzaje kodu s ze sob
wymieszane, a co za tym idzie
znacznie trudniej bdzie modyfikowa
i pielgnowa takie aplikacje. Dziki
separacji kodu mona czu si
bezpieczniej i mie nadziej, e zmiany
funkcjonalne nie spowoduj adnych
problemw w strukturze lub wygldzie
strony. Co wicej, dziki separacji

294

Rozdzia 6.

kodu nad tym samym projektem


mog pracowa osoby o rnych
specjalizacjach i dowiadczeniach.
Na przykad projektant moe
pracowa nad struktur i prezentacj
strony bez obaw, e jego zmiany
spowoduj pojawienie si bdw
w funkcjonalnym kodzie JavaScript,
ktrego projektant moe nie rozumie.

P: Skoro funkcje to tylko dane,


to w jaki sposb mog odrni
funkcj od zwyczajnej zmiennej?

: Rnica pomidzy funkcj


a zwyczajn zmienn sprowadza
si do tego, w jakim celu i jak jej
uywasz. Dane powizane z funkcj
(czyli jej kod) mona wykonywa.
Jeli masz zamiar wywoa funkcj,
to informujesz o tym interpreter
JavaScriptu, umieszczajc za jej nazw
nawiasy oraz w razie potrzeby list
argumentw.

P: Jaki jest cel tworzenia


odwoa do funkcji?

: W odrnieniu od normalnych
zmiennych, ktre przechowuj
powizane z nimi dane jako wartoci
w pamici, funkcje przechowuj
odwoania do swego kodu. A zatem
wartoci zmiennej funkcyjnej nie
jest sam kod funkcji, lecz odwoanie
do miejsca w pamici, w ktrym ten
kod si znajduje. Zatem w przypadku
funkcji zmienna przypomina nieco
adres pocztowy, ktry wskazuje, o jaki
dom chodzi, lecz nie jest tym domem.
Funkcje wykorzystuj odwoania,
a nie faktyczne wartoci, gdy
rozwizanie to jest bardziej efektywne
ni tworzenie i przechowywanie wielu
kopii kodu. A zatem przypisujc
funkcj procedurze obsugi
zdarze (co niebawem) zrobisz,
w rzeczywistoci przypisujesz jedynie
odwoanie do jej kodu, a nie sam kod.

Funkcje

No dobrze, moe i wychodzi na


to, e odwoania do funkcji s super,
ale co one maj wsplnego z separacj
zawartoci od funkcjonalnoci?

*numer zwrotny dla funkcji


Odwoania do funkcji s cile powizane ze specjalnym sposobem
wywoywania funkcji, ktry z kolei ma bardzo duo wsplnego z separacj
zawartoci od funkcjonalnoci. Na przykad spotkae ju ponisze
wywoanie byo ono stosowane w kodzie aplikacji Mandango:

setSeat(i * seats[i].length + j; "select", "Twoje miejsce");

function setSeat(seatNum, status, description) {


...
}

Jednak to nie jest jedyny moliwy sposb wywoywania funkcji. Inne


funkcje, nazywane funkcjami zwrotnymi, mog by wywoywane bez
jakiegokolwiek jawnego dziaania ze strony programisty.

WYT
UMYS

Jak sdzisz, czy takie funkcje zwrotne mogyby si przyda w aplikacji Mandango?
Jeli tak, to w jaki sposb mona by je wykorzysta?

jeste tutaj  295

Funkcja normalna i zwrotna

Pogawdki przy kominku

Temat dzisiejszej pogawdki:


Konfrontacja Funkcji normalnej z Funkcj zwrotn

Funkcja normalna:

Funkcja zwrotna:

A zatem to ty jeste t panienk z okienka, ktra nie


przyjmuje wywoa lokalnych? Skd to stanowisko?
adne tam stanowisko. Po prostu su do innych celw.
Podobnie jak przegldarka WWW wol, gdy wywoania
przychodz do mnie z odlegych, egzotycznych miejsc.
Sucham jak przegldarka? To doprawdy egzotyczne
podejcie. Sdz, e po prostu nie potrafisz si
dogada z tymi spord nas, ktre w normalny sposb
komunikuj si z kodem skryptu.
Suchaj tu nie chodzi o to, ktra z nas jest lepsza lub
gorsza. Wszystkie jestemy czciami kodu, ja po prostu
zapewniam moliwo uzyskania dostpu do kodu
przernym outsiderom. Gdyby nie ja, nie miaaby
pojcia o jakichkolwiek zdarzeniach zachodzcych poza
skryptem.
Te co a czy kogo to w ogle obchodzi? Wcale!
Kto si przejmuje tym, co dzieje si poza skryptem?
Prawd mwic wszyscy. Pamitaj, e celem
tworzenia skryptw jest poprawienie funkcjonalnoci
i atrakcyjnoci stron. Gdyby skrypt nie posiada
adnych sposobw wykrywania zachodzcych poza nim
zdarze i reagowania na nie, to trudno by byo mwi
o poprawianiu czegokolwiek.
Wiesz w tym przypadku moe i masz troch racji.
Lubi wiedzie, kiedy zostanie zakoczone wczytywanie
strony albo kiedy uytkownik co kliknie czy wpisze.
I twierdzisz, e gdyby nie ty, w ogle bym nie wiedziaa
o takich zdarzeniach?
Wanie. Przegldarka wywouje mnie, a ja w wielu
przypadkach wywouj ciebie, poniewa reagowanie na
zdarzenia zewntrzne czsto wymaga wykonania kilku
funkcji.
C, mio usysze, e w rzeczywistoci wcale si tak
bardzo nie rnimy.
No wanie. A zatem, jak sdz, kiedy si jeszcze
spotkamy.
Nie dzwo do mnie, sama si odezw.
Ciekawe ycz powodzenia.

296

Rozdzia 6.

Funkcje

Zdarzenia, funkcje zwrotne i atrybuty HTML


Funkcje zwrotne, wywoywane przez przegldark, a nie przez nasz kod, stosujemy ju
od duszego czasu. Najczciej znajduj one zastosowanie podczas obsugi zdarze.
Na przykad trudno byoby wyobrazi sobie dziaanie aplikacji Mandango bez takich
funkcji zwrotnych. W praktyce problem mieszania kodu HTML i JavaScript w bardzo
duym stopniu dotyczy wanie funkcji obsugujcych zdarzenia.

Przegldarka wywouje
funkcj initSeats() po
zakoczeniu wczytywania
strony.

onload!
initSeats();

onclick!
showSeatStatus(23);

Funkcje zwrotne s kojarzone ze zdarzeniami w kodzie HTML aplikacji


Mandango:
Atry

<body onload="initSeats();">

but onload jzyka HTML umo


skojarzenie funkcji initSeats() ze liwia
zdarzeniem onload.

<img id="seat26" src="" alt="" onclick="showSeatStatus(23);" />


Atrybut onclick jzyka HTML
umoliwia skojarzenie funkcji
showSeatStatus() ze zdarzeniem
onclick.

Czy mog
oddzwoni?

Ta technika kojarzenia funkcji obsugujcych zdarzenia ze zdarzeniami


przy wykorzystaniu atrybutw HTML dziaa doskonale, jednak ma
pewn wad wymaga mieszania kodu HTML i JavaScript. Na
szczcie odwoania do funkcji pozwalaj unikn tego niepotrzebnego
baaganu i odseparowa oba rodzaje kodu.

jeste tutaj  297

Unikanie mieszania kodu przy uyciu odwoa do funkcji

Okrelanie procedur obsugi zdarze przy uyciu


odwoa do funkcji
Zamiast kojarzy funkcje zwrotne z procedurami obsugi zdarze, uywajc w tym celu
atrybutw HTML, mona to zrobi bezporednio w kodzie HTML. Innymi sowy, w ogle
nie bdziesz musia ingerowa w kod HTML wystarczy okreli funkcj zwrotn,
uywajc odwoania do funkcji, a wszystko wycznie z poziomu kodu JavaScript.
Za nazw funkcji nie
ma nawiasw, gdy nie
chcemy wywoywa tej
funkcji interesuje nas
odwoanie do niej.

window.onload = initSeats;
zostaje
Odwoanie do funkcji initSeats()
ad.
onlo
ci
ciwo
wa
we
zapisane

Zdarzenie onload jest


waciwoci obiektu window.

Jak zatem wida, okrelenie procedury obsugi zdarze z poziomu kodu JavaScript
polega na zapisaniu odwoania do funkcji w odpowiedniej waciwoci odpowiedniego
obiektu. W powyszym przykadzie przypisanie odwoania do funkcji we waciwoci
onload sprawi, e kade zgoszenie zdarzenia onload spowoduje wywoanie funkcji
initSeats(). Co wicej, wywoanie funkcji nastpuje automatycznie w odpowiedzi na
zgoszenie zdarzenia. Oto, jak wyglda ten proces:

window.onload();

onload!

Zdarzenie onload wywouje


procedur obsugi zdarze za
porednictwem waciwoci
window.onload

initSeats();

a poniewa we waciwoci
tej zostao zapisane odwoanie
do funkcji, zatem w celu obsugi
zdarzenia onload zostanie wywoana
funkcja initSeats().

Ogromn zalet wykorzystania odwoa do funkcji i waciwoci obiektw w celu


okrelenia funkcji obsugujcych zdarzenia jest moliwo cakowitego odseparowania
kodu JavaScript od kodu HTML nie ma ju potrzeby umieszczania jakiegokolwiek
kodu JavaScript w atrybutach znacznikw HTML.
<body onload=initSeats();>

<body>

W kocu znacznik <body> moe pozosta znacznikiem <body>, gdy funkcja obsugujca
zdarzenia onload zostaa okrelona z poziomu kodu JavaScript. Musimy tylko zadba
o to, by kod okrelajcy funkcj obsugujc zdarzenia zosta wykonany moliwie jak
najwczeniej; dlatego te zazwyczaj jest on umieszczany w sekcji nagwka strony.
Jest jednak pewien problem. Co zrobi, gdy do funkcji obsugujcej zdarzenia musimy
przekaza jaki argument, konieczny do jej prawidowego wykonania? Problem ten
nie wystpuje w przypadku zdarze onload uywanych w aplikacji Mandango, jednak
prawidowe obsuenie zdarzenia onclick wymaga ju przekazania argumentu numeru
kliknitego miejsca. Odwoania do funkcji nie umoliwiaj przekazywania argumentw
a zatem musimy przyjrze si temu zagadnieniu dokadniej.

298

Rozdzia 6.

Odwoania
zapewniaj
wygodny sposb
powizania funkcji
ze zdarzeniami,
ktre te funkcje
maj obsugiwa.

Funkcje

Literay funkcyjne spiesz z odsiecz


W wyniku kliknicia obrazka fotela w aplikacji Mandango ma zosta
wywoana funkcja showSeatStatus(), a do niej przekazany argument
liczba okrelajca numer kliknitego miejsca. W tym przypadku
zwyczajne przypisanie odwoania do funkcji nie zda egzaminu, gdy
nie pozwoli nam przekaza argumentu. Mamy zatem problem. Na
szczcie istnieje pewne rozwizanie. Polega ono na uyciu literau
funkcyjnego do utworzenia odwoania do funkcji i wywoaniu funkcji
showSeatStatus() z okrelonym argumentem wewntrz tego literau.

onclick!

a fotela, aby
Pobieramy obiekt obrazk
waciwoci
o
jeg
do
uzyska dostp
onclick.

document.getElementById("seat23").onclick = function(evt) {
showSeatStatus(23);
};
Litera funkcyjny zawiera wywoanie
metody showSeatStatus(), dziki
czemu moemy przekaza do niej
argument.

Litera funkcyjny
jest zapisywany we
waciwoci onclick jako
odwoanie do funkcji.

Litera funkcyjny jest uywany wycznie jako pojemnik, w ktrym zostanie


umieszczone wywoanie funkcji showSeatStatus(); niemniej peni on
kluczow rol, gdy zapewnia moliwo przekazania do niej argumentu
okrelajcego numer kliknitego miejsca. Moesz wyobrazi sobie ten litera
funkcyjny jako bezimienn funkcj obsugujc zdarzenia. Wanie z tego
powodu literay funkcyjne s take nazywane funkcjami anonimowymi.
Powyszy kod pokazuje, e JavaScript udostpnia obiekt zdarzenia, ktry
jest przekazywany do procedury obsugi zdarze, w tym przypadku pod
postaci argumentu evt. Obiekt ten zawiera informacje charakterystyczne
dla konkretnego typu zdarzenia. W tym przypadku nie interesuj nas adne
dodatkowe informacje o zdarzeniu, zatem moemy zignorowa argument evt
i w ogle go nie uywa.

wiczenie

e
Obiekt zdarzenia jest automatyczni
ugi
obs
y
edur
proc
do
y
wan
przekazy
jej
zdarze jako pierwszy argument
wywoania.

Literay funkcyjne
pozwalaj nam tworzy
anonimowe funkcje
obsugujce zdarzenia.

Skojarz funkcj initSeats() z procedur obsugi zdarze onload, uywajc do tego celu literau funkcyjnego,
a nie odwoania do funkcji.
...............................................................................................................................
...............................................................................................................................
...............................................................................................................................

jeste tutaj  299

Rozwizanie wiczenia

Skojarz funkcj initSeats() z procedur obsugi zdarze onload, uywajc do tego celu literau funkcyjnego,
a nie odwoania do funkcji.

wiczenie
window.onload = function(evt) {
Rozwizanie ...............................................................................................................................
initSeats();
...............................................................................................................................
};
...............................................................................................................................
Funkcja initSeats() jest
wywoywana wewntrz literau
funkcyjnego obsugujcego
zdarzenie onload.

Argument evt jest ignorowany,


gdy procedura obsugi zdarze
onload nie potrzebuje adnych
informacji o zdarzeniu.

Czym jest kojarzenie?


Wci pozostaje nam do rozwizania jeden problem zwizany z kojarzeniem procedur
obsugi zdarze przy wykorzystaniu literaw funkcyjnych. Wiemy ju, e procedur
obsugi zdarze onload moemy okreli w sekcji nagwka strony WWW, w znaczniku
<script>, uywajc w tym celu zwyczajnego kodu JavaScript. Rozwizanie to bdzie
dziaa dobrze, gdy kod takiej procedury zostanie wykonany dopiero po zakoczeniu
wczytywania strony (bo wanie wtedy generowane jest zdarzenie onload), czyli w tym
samym momencie, w ktrym zostaaby wywoana funkcja initSeats() umieszczona
w kodzie HTML w atrybucie onload znacznika <body>. Rodzi si jednak pytanie: Kiedy
nastpuje skojarzenie innych literaw funkcyjnych z procedurami obsugi zdarze?.
Aby odpowiedzie na to pytanie, powinnimy wrci do funkcji zwrotnej obsugujcej
zdarzenia onload, ktra jest idealnym miejscem na okrelenie wszystkich pozostaych
procedur obsugi zdarze wykorzystywanych na stronie.
window.onload = function() {
// Skojarzenie innych procedur obsugi zdarze

Kod obsugujcy
zdarzenie onload
jest doskonaym
miejscem do
okrelenia procedur
obsugi wszelkich
innych zdarze.

W ramach obsugi zdarzenia onlo


ad
mona okreli procedury obsugi
wszystkich innych zdarze uyw
anych
na stronie.

...
// Inicjalizacja prezentacji
initSeats();
}

Kod, ktry jest cile zwizany


z obsug zdarzenia onload,
take zostanie wykonany w tej
procedurze obsugi zdarzenia.

Powyszy przykad wyranie pokazuje, e procedura obsugi zdarzenia onload staje si


centralnym miejscem, w ktrym okrelane s wszystkie inne procedury obsugi zdarze
wykorzystywane na stronie. A zatem procedura ta nie tylko wykonuje standardowe
czynnoci inicjalizacyjne, takie jak okrelenie wygldu poszczeglnych miejsc, lecz
take okrela pozostae procedury obsugi zdarze.

300

Rozdzia 6.

Funkcje

Nie ma

niemdrych pyta

P: Dlaczego funkcje zwrotne

P: Czy funkcje zwrotne to co

maj takie znaczenie?

innego ni procedury obsugi


zdarze?

: Funkcje zwrotne s bardzo wane,


gdy pozwalaj reagowa na zdarzenia
zachodzce poza Twoim kodem. Zamiast
wywoywa funkcj ze swojego kodu,
tworzysz funkcj, ktra oczekuje na pewne
zdarzenia i jest gotowa do ich obsugi.
Kiedy takie zdarzenie nastpi, przegldarka
ma obowizek poinformowa o tym
fakcie odpowiedni funkcj zwrotn, czyli
w rezultacie wywoa j. Cae Twoje zadanie
polega na przygotowaniu teatru przyszych
zdarze, czyli skojarzeniu funkcji zwrotnej
z czynnikiem, ktry ma powodowa jej
wykonanie, takim jak zdarzenie.

O: Tak. Inny czsto spotykany sposb

wykorzystania funkcji zwrotnych


przedstawimy w rozdziale 12.
Wykorzystamy je tam do obsugi danych
przesyanych z serwera do przegldarki przy
wykorzystaniu techniki Ajax.

P: Wci nie do koca czuj


literay funkcyjne. Czym one s
i niby dlaczego s takie wane?

: Litera funkcyjny to sama tre funkcji, bez


adnej nazwy, czyli co podobnego do kadej
innej informacji, takiej jak acuch znakw lub
liczba. S one wane, gdy doskonale nadaj
si do uycia w sytuacjach, gdy potrzeba

nam szybkiej, jednorazowej funkcji zwrotnej,


czyli wtedy, gdy potrzeba nam funkcji, ktra
zostanie wywoana tylko raz i to w dodatku
nie przez nasz kod. A zatem z powodzeniem
mona stworzy litera funkcyjny i przypisa
go bezporednio do waciwoci obsugi
zdarzenia. Rozwizanie to da identyczne
efekty co stworzenie normalnej, nazwanej
funkcji i przypisanie odwoania do niej.
W praktyce stosowanie literaw funkcyjnych
sprowadza si zatem do efektywnoci pisania
kodu, gdy jest wygodne w sytuacjach, gdy
tworzenie zwyczajnych, nazwanych funkcji nie
jest konieczne. Nie naley take zapomina,
e w rzeczywistoci literay funkcyjne s
konieczne tylko w bardziej zoonych
sytuacjach, kiedy zwyczajne odwoania
do funkcji oka si niewystarczajce; na
przykad gdy konieczne bdzie przekazanie
argumentw do funkcji zwrotnej.

Zaostrz owek
Uzupenij brakujcy kod nowej wersji procedury obsugi zdarzenia onload aplikacji Mandango.

window.onload = function() {
miejsc
// Skojarzenie procedury obsugi kliknicia przycisku Szukaj
;
.......
.......
=
.......
document.getElementById("findseats")......
// Skojarzenie procedury obsugi kliknicia
document.getElementById("seat0")..........
document.getElementById("seat1")..........
document.getElementById("seat2")..........

obrazka miejsca
= function(evt){.............};
= function(evt){.............};
= function(evt){.............};

...
// Inicjalizacja prezentacji
..........
}

jeste tutaj  301

Rozwizanie wiczenia

Zaostrz owek
Rozwizanie

Uzupenij brakujcy kod nowej wersji procedury obsugi zdarzenia onload aplikacji
Mandango.
Funkcja findSeats() jest kojarzona
ze zdarzeniem onclick przy uyciu
odwoania do funkcji.

Caa procedura obsugi


zdarzenia onload jest jednym
duym literaem funkcyjnym.

window.onload = function() {
miejsc
// Skojarzenie procedury obsugi kliknicia przycisku Szukaj
ts
findSea
onclick
;
.......
document.getElementById("findseats")............. = .......
// Skojarzenie procedury obsugi kliknicia obrazka miejsca
showSeatStatu
onclick
....};
.......s(0);
.......
document.getElementById("seat0").......... = function(evt){
s(1);
atStatu
showSe...........};
onclick
.......
document.getElementById("seat1").......... = function(evt){
showSeatStatu
....};
.......s(2);
onclick
.......
document.getElementById("seat2").......... = function(evt){
...

// Inicjalizacja prezentacji
initSeats();
...
.......
}

W kocu wywoywana jest funkcja


initSeats(), ktra koczy obsug
zdarzenia onload.

Podczas okrelania procedur


obsugi zdarze obrazkw
poszczeglnych miejsc
korzystamy z waciwoci
onclick odpowiednich obiektw
strony.

Funkcja showSeatStatus() jest


wywoywana wewntrz literau
a
funkcyjnego, dziki czemu mon
do niej przekaza argument.

KLUCZOWE ZAGADNIENIA
Funkcje zwrotne s wywoywane przez przegldark
w odpowiedzi na zdarzenia zachodzce poza skryptem.
Odwoa do funkcji mona uywa do przypisywania
funkcji w taki sposb, jak gdyby byy zwyczajnymi
zmiennymi.

302

Rozdzia 6.

Odwoania do funkcji pozwalaj kojarzy funkcje ze


zdarzeniami, ktre maj by obsugiwane, z poziomu kodu
JavaScript, bez koniecznoci wprowadzania jakichkolwiek
zmian w kodzie HTML.
Literay funkcyjne to bezimienne funkcje, ktre
z powodzeniem mona wykorzystywa wtedy, gdy stosowanie
zwyczajnych, nazwanych funkcji nie jest konieczne.

Funkcje

Nie ma

niemdrych pyta

: Dlaczego procedura obsugi zdarzenia onload


w aplikacji Mandango zostaa stworzona jako
litera funkcyjny?

: Czy inne procedury obsugi zdarze musz


by okrelane wewntrz procedury obsugi
zdarze onload?

O: Poniewa nie ma powodu tworzy w tym celu zwyczajnej, O: Tak. Moesz sdzi, e nic nie stoi na przeszkodzie, by
nazwanej funkcji. Funkcja ta jest wywoywana tylko raz
w odpowiedzi na zdarzenie onload. Oczywicie nic nie stoi na
przeszkodzie, bymy utworzyli zwyczajn funkcj i przypisali
odwoanie do niej we waciwoci window.onload; jednak
powizanie pomidzy zdarzeniem i funkcj zwrotn jest
bardziej czytelne i zrozumiae w przypadku uycia literau
funkcyjnego ni odwoania do funkcji.

Struktura strony HTML


Oddzielenie kodu JavaScript od kodu HTML pokazuje, jak
niewielka i prosta jest w rzeczywistoci strukturalna cz
strony aplikacji Mandango. Dziki usuniciu podatnego na
bdy kodu JavaScript kod HTML strony sta si znacznie
atwiejszy do utrzymania.

Chopie,
musz zrobi
zdjcie tego kodu!

Spjrz na ten
kod! Jest taki
prosty i atwy
w utrzymaniu!

okreli je wewntrz znacznika <script> umieszczonego


w sekcji nagwka strony; pamitaj jednak, e w tym
momencie zawarto strony nie jest jeszcze w caoci
wczytana do przegldarki, co oznacza, e wywoania
metody getElementById() mogyby nie znale danych
elementw, a procedury obsugi zdarze nie zostayby
okrelone. Zgoszenie zdarzenia onload gwarantuje, e caa
zawarto strony bdzie ju wczytana.

<body>
<div style="margin-top:25px; text-align:center">
<img id="seat0" src="" alt="" />
<img id="seat1" src="" alt="" />
<img id="seat2" src="" alt="" />
<img id="seat3" src="" alt="" />
<img id="seat4" src="" alt="" />
<img id="seat5" src="" alt="" />
<img id="seat6" src="" alt="" />
<img id="seat7" src="" alt="" />
<img id="seat8" src="" alt="" /><br />
<img id="seat9" src="" alt="" />
<img id="seat10" src="" alt="" />
<img id="seat11" src="" alt="" />
<img id="seat12" src="" alt="" />
<img id="seat13" src="" alt="" />
<img id="seat14" src="" alt="" />
<img id="seat15" src="" alt="" />
<img id="seat16" src="" alt="" />
<img id="seat17" src="" alt="" /><br />
<img id="seat18" src="" alt="" />
<img id="seat19" src="" alt="" />
<img id="seat20" src="" alt="" />
<img id="seat21" src="" alt="" />
<img id="seat22" src="" alt="" />
<img id="seat23" src="" alt="" />
<img id="seat24" src="" alt="" />
<img id="seat25" src="" alt="" />
<img id="seat26" src="" alt="" /><br />
<img id="seat27" src="" alt="" />
<img id="seat28" src="" alt="" />
<img id="seat29" src="" alt="" />
<img id="seat30" src="" alt="" />
<img id="seat31" src="" alt="" />
<img id="seat32" src="" alt="" />
<img id="seat33" src="" alt="" />
<img id="seat34" src="" alt="" />
<img id="seat35" src="" alt="" /><br />
<input type="button" id="findseats" value="Szukaj miejsc"
/>
</div>
</body>

jeste tutaj  303

Funkcjonalny JavaScript

May krok dla JavaScriptu


Cho nie udao si nam rozwiza problemu pokoju na wiecie, to jednak zrobilimy krok
w dobrym kierunku, wykorzystujc JavaScript do sterowania temperatur w naszym domu.
Podzia duych problemw na mae, skoncentrowanie uwagi na pojedynczych, konkretnych
zadaniach i moliwo wielokrotnego stosowania kodu oto, w jaki sposb funkcje mog
poprawi pisany przez nas kod JavaScript.

Budownictwo

Obecnie midzy
mn i Mandango
zapanowa pokj.

Te tak to
czuj.

Schronienie

Szymek i Jasiek zastosowali dokadnie te same techniki rozwizywania


problemw, dziki ktrym udao si im stworzy lepiej zorganizowan
i atwiejsz do utrzymania wersj aplikacji Mandango. Moe to nie jest
zbyt wiele, ale przynajmniej w wiecie prawdziwych macho chodzcych
z kumplem do kina zapanowa spokj

Przedni rzd miejsc!

304

Rozdzia 6.

Funkcje

Zaginarka stron
Zegnij stron wzdu pionowych
linii, tak by oba mzgi si
poczyy, a nastpnie rozwi
zagadk.

Co nowego dodaj funkcje do ycia


Twojego kodu JavaScript?
To spotkanie umysw!

Poywienie

Ciepo
tu. W takiej temperaturze
nie czuj si najlepiej.

Tak mi
zimno.

Schronienie

Prawa
obywatelskie

Pokj zawsze jest trudnym zagadnieniem.


Nawet w wiecie JavaScriptu jedynie kod o najlepszej
organizacji moe zapewni spokj.
Nie jest zatem atwo zapewni sobie spokojny i komfort-owy byt przynajmniej w wiecie JavaScriptu.

jeste tutaj  305

You might also like