Rozdzia┼é 2. Podstawy JavaScriptu. Warto┼Ťci, zmienne i kontrola sterowania

> Dodaj do ulubionych

W ┼Ťwiecie komputer├│w istniej─ů tylko dane. Je┼Ťli co┼Ť nie jest informacj─ů, to po prostu nie istnieje. Mimo ┼╝e wszystkie dane to w istocie jedynie sekwencje bit├│w 1, a wi─Öc zasadniczo s─ů tym samym, ka┼╝da informacje odgrywa jak─ů┼Ť rol─Ö. W systemie JavaScriptu wi─Ökszo┼Ť─ç danych jest zgrabnie wyodr─Öbniona w postaci tzw. warto┼Ťci. Ka┼╝da warto┼Ť─ç ma typ determinuj─ůcy, jak─ů rol─Ö ta warto┼Ť─ç mo┼╝e pe┼éni─ç. Wyr├│┼╝nia si─Ö sze┼Ť─ç podstawowych typ├│w danych: liczby, ┼éa┼äcuchy, warto┼Ťci logiczne, obiekty, funkcje oraz warto┼Ťci niezdefiniowane.

Aby utworzy─ç warto┼Ť─ç, wystarczy nada─ç jej nazw─Ö. Jest to bardzo wygodne. Nie trzeba gromadzi─ç materia┼é├│w do budowy warto┼Ťci, ani za nie p┼éaci─ç. Wystarczy tylko nada─ç jej nazw─Ö i abrakadabra, gotowe. Chocia┼╝ oczywi┼Ťcie warto┼Ťci nie bior─ů si─Ö z niczego. Ka┼╝da musi by─ç gdzie┼Ť zapisana i je┼Ťli utworzysz gigantyczn─ů liczb─Ö warto┼Ťci na raz, to mo┼╝e zabrakn─ů─ç Ci miejsca w pami─Öci komputera. Na szcz─Ö┼Ťcie problem ten dotyczy tylko sytuacji, w kt├│rych wszystkie te warto┼Ťci s─ů potrzebne na raz. Gdy warto┼Ť─ç przestaje by─ç u┼╝ywana, zostaje usuni─Öta i pozostaje po niej tylko kilka bit├│w. Bity te s─ů odzyskiwane, aby mo┼╝na by┼éo ich u┼╝y─ç do przechowywania nast─Öpnych warto┼Ťci.


Warto┼Ťci liczbowe

Warto┼Ťci typu liczbowego to, jak si─Ö mo┼╝na spodziewa─ç, liczby. Zapisuje si─Ö je tak, jak normalne liczby:

144

Je┼Ťli wpiszesz t─Ö liczb─Ö w konsoli, w oknie wyj┼Ťciowym poka┼╝e si─Ö ta sama liczba. Wpisany przez Ciebie tekst spowodowa┼é utworzenie warto┼Ťci liczbowej, a konsola wy┼Ťwietli┼éa j─ů na ekranie. Ten przyk┼éad niczego ciekawego nie pokazuje, ale wkr├│tce b─Ödziemy tworzy─ç warto┼Ťci na inne sposoby i w├│wczas mo┼╝liwo┼Ť─ç wypr├│bowania tego, co si─Ö utworzy┼éo w konsoli b─Ödzie bardzo przydatna.

A tak wygl─ůda liczba 144 w postaci bitowej2:

0100000001100010000000000000000000000000000000000000000000000000

Powy┼╝sza liczba sk┼éada si─Ö z 64 bit├│w. Z tylu bit├│w sk┼éadaj─ů si─Ö wszystkie liczby w j─Özyku JavaScript, co ma jeden wa┼╝ny skutek: ilo┼Ť─ç liczb, jakie mo┼╝na w ten spos├│b wyrazi─ç jest ograniczona. Za pomoc─ů trzech cyfr dziesi─Ötnych mo┼╝na wyrazi─ç tylko liczby od 0 do 999, czyli 103 = 1000 r├│┼╝nych liczb. Przy u┼╝yciu 64 cyfr binarnych mo┼╝na zapisa─ç 264 r├│┼╝nych liczb. To bardzo du┼╝o, wi─Öcej ni┼╝ 1019 (jedynka z dziewi─Ötnastoma zerami).

Jednak nie wszystkie liczby ca┼ékowite mniejsze od 1019 dadz─ů si─Ö wyrazi─ç przy u┼╝yciu typ├│w liczbowych j─Özyka JavaScript. Jednym z powod├│w jest to, ┼╝e istniej─ů r├│wnie┼╝ liczby ujemne i jeden bit musi zosta─ç u┼╝yty do przechowywania znaku liczby. Jeszcze wi─Ökszym problemem jest to, ┼╝e reprezentowane musz─ů by─ç liczby nie b─Öd─ůce ca┼ékowitymi. Dlatego 11 bit├│w jest u┼╝ywanych do przechowywania informacji o po┼éo┼╝eniu kropki oddzielaj─ůcej cz─Ö┼Ť─ç ca┼ékowit─ů od u┼éamkowej.

W ten spos├│b pozostaj─ů 52 bity3. Ka┼╝da liczba ca┼ékowita mniejsza od 252 (co jest wi─Öcej ni┼╝ 1015) da si─Ö bez problemu wyrazi─ç w JavaScripcie. Zazwyczaj u┼╝ywa si─Ö o wiele mniejszych liczb i opisane problemy w og├│le nas nie dotycz─ů. Bardzo dobrze. Nie mam nic przeciwko bitom, ale ┼╝eby cokolwiek zrobi─ç, trzeba mie─ç ich ogromn─ů ilo┼Ť─ç. Gdy jest to mo┼╝liwe, przyjemniej jest pos┼éugiwa─ç si─Ö wi─Ökszymi obiektami.

Liczby ułamkowe zapisuje się z użyciem kropki.

9.81

Do wyrażania bardzo dużych i bardzo małych liczb można też używać notacji naukowej. W tym celu należy dodać literę e i wykładnik potęgi:

2.998e8

Powy┼╝szy zapis jest r├│wnowa┼╝ny z 2.998 * 108 = 299800000.

Dzia┼éania wykonywane na liczbach ca┼ékowitych mieszcz─ůcych si─Ö w granicy 52 bit├│w s─ů zawsze dok┼éadne. Niestety tego samego nie mo┼╝na powiedzie─ç o liczbach u┼éamkowych. Tak samo, jak nie mo┼╝na przy u┼╝yciu sko┼äczonej liczby cyfr dziesi─Ötnych precyzyjnie okre┼Ťli─ç warto┼Ťci liczby ¤Ç (pi), wielu liczb nie mo┼╝na precyzyjnie wyrazi─ç przy u┼╝yciu tylko 64 bit├│w. Szkoda, ale tak naprawd─Ö powoduje to realne problemy tylko w pewnych specyficznych sytuacjach. Wa┼╝ne jest, aby o tym pami─Öta─ç i traktowa─ç u┼éamkowe liczby dziesi─Ötne jako przybli┼╝enia, a nie dok┼éadne warto┼Ťci.


Działania arytmetyczne

Liczb najcz─Ö┼Ťciej u┼╝ywa si─Ö do wykonywania dzia┼éa┼ä arytmetycznych. Dzia┼éania te, np. dodawanie czy mno┼╝enie, polegaj─ů na pobraniu dw├│ch liczb i utworzeniu z nich nowej warto┼Ťci. W j─Özyku JavaScript wygl─ůda to tak:

100 + 4 * 11

Znaki + i * nazywaj─ů si─Ö operatorami. Pierwszy oznacza dodawanie, a drugi mno┼╝enie. Umieszczenie operatora mi─Ödzy dwiema warto┼Ťciami powoduje zastosowanie go do tych warto┼Ťci i utworzenie nowej warto┼Ťci.

Czy ten przyk┼éad oznacza „dodaj 4 do 100, a nast─Öpnie pomn├│┼╝ otrzymany wynik przez 11”, czy mo┼╝e jednak mno┼╝enie zostanie wykonane przed dodawaniem? Jak zapewne zgad┼ée┼Ť, najpierw wykonane zostanie mno┼╝enie. Ale, podobnie jak w matematyce, mo┼╝na to zmieni─ç za pomoc─ů nawias├│w:

(100 + 4) * 11

Do odejmowania s┼éu┼╝y operator -, a do dzielenia —/. Gdy w wyra┼╝eniu znajduje si─Ö kilka operator├│w i nie ma ┼╝adnych nawias├│w, dzia┼éania s─ů wykonywane zgodnie z zasadami kolejno┼Ťci wykonywania dzia┼éa┼ä. W pierwszym przyk┼éadzie udowodni┼éem, ┼╝e mno┼╝enie ma pierwsze┼ästwo przed dodawaniem. Dzielenie i mno┼╝enie s─ů zawsze wykonywane przed odejmowaniem i dodawaniem. Je┼Ťli obok siebie wyst─ůpi─ů operatory o takim samym priorytecie (1 - 1 + 1), to s─ů wykonywane po kolei od lewej.

Spr├│buj obliczy─ç wynik poni┼╝szego wyra┼╝enia, a potem wykonaj program, aby sprawdzi─ç, czy dobrze policzy┼ée┼ŤÔÇŽ

115 * 4 - 4 + 88 / 2

Nie musisz jednak zbytnio przejmowa─ç si─Ö zasadami kolejno┼Ťci wykonywania dzia┼éa┼ä, poniewa┼╝ w razie w─ůtpliwo┼Ťci zawsze mo┼╝esz u┼╝y─ç nawias├│w.

Istnieje jeszcze jeden operator arytmetyczny, którego możesz nie znać. Oznacza się go symbolem % i reprezentuje on działanie zwracania reszty z dzielenia. Wynikiem działania X % Y będzie reszta z podzielenia X przez Y. Na przykład 314 % 100 wynosi 14, 10 % 3 wynosi 1, a 144 % 12 równa się 0. Reszta z dzielenia ma taki sam priorytet, jak mnożenie i dzielenie.


Typ łańcuchowy

Drugi typ danych to ┼éa┼äcuch. Jego przeznaczenie nie jest w tak oczywisty spos├│b zwi─ůzane z nazw─ů, jak w przypadku liczb, ale ten typ r├│wnie┼╝ jest bardzo potrzebny. ┼üa┼äcuchy s┼éu┼╝─ů do reprezentowania tekstu, a ich nazwa zapewne wzi─Ö┼éa si─Ö st─ůd, ┼╝e warto┼Ťci tego typu s─ů po prostu ci─ůgami znak├│w. ┼üa┼äcuchy zapisuje si─Ö cudzys┼éowach prostych:

"Za┼éataj moj─ů ┼é├│dk─Ö gum─ů do ┼╝ucia."

W podw├│jnym cudzys┼éowie mo┼╝na wpisa─ç prawie wszystko, a JavaScript zrobi z tego warto┼Ť─ç ┼éa┼äcuchow─ů. Jest jednak kilka znak├│w, na kt├│re trzeba uwa┼╝a─ç. Po pierwsze trudno┼Ťci w cudzys┼éowie sprawiaj─ů w┼éa┼Ťnie cudzys┼éowy. Po drugie problemy mo┼╝esz mie─ç ze wstawianiem znak├│w nowego wiersza, czyli tych znak├│w, kt├│re s─ů wstawiane, gdy u┼╝ytkownik naci┼Ťnie klawisz Enter. Ich r├│wnie┼╝ nie mo┼╝na umieszcza─ç w cudzys┼éowach, poniewa┼╝ ka┼╝dy ┼éa┼äcuch musi w ca┼éo┼Ťci znajdowa─ç si─Ö w jednym wierszu.

Do wstawiania tych znak├│w do ┼éa┼äcuch├│w u┼╝ywa si─Ö sztuczki. Uko┼Ťnik () w cudzys┼éowie oznacza, ┼╝e znak znajduj─ůcy si─Ö za nim ma specjalne znaczenie. Je┼Ťli za uko┼Ťnikiem znajduje si─Ö cudzys┼é├│w prosty, to cudzys┼é├│w ten nie spowoduje zako┼äczenia ┼éa┼äcucha, ale stanie si─Ö jego cz─Ö┼Ťci─ů. Natomiast znak n za uko┼Ťnikiem oznacza nowy wiersz. Analogicznie t za uko┼Ťnikiem oznacza tabulator4.

"To jest pierwszy wiersz\nA to jest drugi wiersz"

Je┼Ťli wpiszesz ten tekst w konsoli, to zostanie on wy┼Ťwietlony w oknie wyj┼Ťciowym w niezmienionej formie, tzn. z cudzys┼éowami i uko┼Ťnikami. Aby zobaczy─ç sam wynik, mo┼╝esz wpisa─ç np. print("anb"). Dzia┼éanie tej instrukcji zostanie szczeg├│┼éowo obja┼Ťnione p├│┼║niej.

Oczywi┼Ťcie zdarza si─Ö te┼╝, ┼╝e w tek┼Ťcie ma znajdowa─ç si─Ö sam uko┼Ťnik jako jeden ze zwyk┼éych znak├│w. Aby umie┼Ťci─ç uko┼Ťnik w ┼éa┼äcuchu, nale┼╝y wpisa─ç dwa uko┼Ťniki bezpo┼Ťrednio obok siebie:

"Znak nowego wiersza zapisuje si─Ö tak: "\n"."

┼üa┼äcuch├│w nie mo┼╝na dzieli─ç, mno┼╝y─ç ani odejmowa─ç. Mo┼╝na natomiast u┼╝ywa─ç z nimi operatora +. Jednak w przypadku ┼éa┼äcuch├│w operator ten nie dodaje tylko wykonuje konkatenacj─Ö, czyli po prostu ┼é─ůczenie.

"kon" + "kat" + "e" + "nacja"

Na łańcuchach można wykonywać także inne działania, ale wrócimy do tego później.


Nie wszystkie operatory maj─ů posta─ç symboliczn─ů. Niekt├│re wyst─Öpuj─ů jako s┼éowa. Na przyk┼éad operator typeof tworzy warto┼Ť─ç ┼éa┼äcuchow─ů reprezentuj─ůc─ů typ podanej mu warto┼Ťci.

typeof 4.5

Operatory, kt├│re pozna┼ée┼Ť wcze┼Ťniej dzia┼éa┼éy na dw├│ch argumentach, natomiast typeof pobiera tylko jeden. Operatory wykonuj─ůce dzia┼éania na dw├│ch argumentach nazywaj─ů si─Ö binarnymi lub dwuargumentowymi, natomiast dzia┼éaj─ůce na pojedynczych warto┼Ťciach to operatory jednoargumentowe. Operator minus mo┼╝e by─ç u┼╝ywany zar├│wno jako dwu- jak i jednoargumentowy:

- (10 - 2)

Warto┼Ťci logiczne

Kolejnym typem warto┼Ťci s─ů warto┼Ťci logiczne. S─ů tylko dwie takie warto┼Ťci: true i false. Oto jeden ze sposob├│w na uzyskanie warto┼Ťci true:

3 > 2

Natomiast false mo┼╝na otrzyma─ç tak:

3 < 2

Mam nadziej─Ö, ┼╝e wiesz, co oznaczaj─ů znaki > i <. S─ů to odpowiednio znak wi─Ökszo┼Ťci i mniejszo┼Ťci. S─ů to operatory dwuargumentowe, a wynikiem ich dzia┼éania jest warto┼Ť─ç logiczna oznaczaj─ůca, czy dane wyra┼╝enie jest prawdziwe, czy fa┼észywe.

W ten sam sposób można porównywać łańcuchy:

"Aardvark" < "Zoroaster"

┼üa┼äcuchy s─ů porz─ůdkowane mniej wi─Öcej alfabetycznie. Mniej wi─ÖcejÔÇŽ Wielkie litery s─ů zawsze „mniejsze” od ma┼éych, a wi─Öc warto┼Ťci─ů wyra┼╝enia "Z" < "a" (wielka litera Z i ma┼éa litera a) jest true. Znaki nie nale┼╝─ůce do alfabetu (!, @, itd.) r├│wnie┼╝ s─ů uwzgl─Ödniane w porz─ůdkowaniu. W rzeczywisto┼Ťci por├│wnywanie znak├│w odbywa si─Ö na podstawie standardu Unicode. W standardzie tym ka┼╝demu znakowi, jaki sobie mo┼╝na wyobrazi─ç, od znak├│w greckiego alfabetu przez arabski, japo┼äski i tamilski a┼╝ po polski, przypisany jest numer. Numery te u┼éatwiaj─ů przechowywanie ┼éa┼äcuch├│w w komputerze, poniewa┼╝ mo┼╝na je zapisywa─ç jako listy liczb. Podczas por├│wnywania ┼éa┼äcuch├│w JavaScript por├│wnuje po prostu numery znak├│w w tych ┼éa┼äcuchach od lewej.

Inne operatory tego typu to >= (wi─Ökszy lub r├│wny), <= (mniejszy lub r├│wny), == (r├│wny) oraz != (r├│┼╝ny).

"Szast" != "Prast"
5e2 == 500

Operatory logiczne

Na warto┼Ťciach logicznych mo┼╝na te┼╝ wykonywa─ç pewne dzia┼éania, kt├│re s─ů bardzo przydatne. JavaScript obs┼éuguje trzy operatory logiczne: i, lub oraz nie. Mo┼╝na ich u┼╝ywa─ç do „rozumowania” o warto┼Ťciach logicznych.

Logiczne and jest reprezentowane przez operator &&. Jest to operator logiczny, kt├│ry zwraca warto┼Ť─ç true tylko wtedy, gdy oba jego argumenty maj─ů warto┼Ť─ç true.

true && false

Operator || to logiczne lub. Zwraca warto┼Ť─ç true, gdy kt├│rykolwiek z jego argument├│w ma warto┼Ť─ç true:

true || false

Operator logicznego nie ma posta─ç wykrzyknika (!). Jest to operator jednoargumentowy zamieniaj─ůcy podan─ů mu warto┼Ť─ç na przeciwn─ů, a wi─Öc !true oznacza false, a !false oznacza true.


─ćw. 2.1
((4 >= 6) || ("zielona" != "trawa")) &&

   !(((12 * 2) == 144) && true)

Prawda czy fa┼ész? W kodzie tym znajduje si─Ö sporo nawias├│w, kt├│re u┼éatwiaj─ů jego zrozumienie, ale nie s─ů niezb─Ödne. Mo┼╝na go zapisa─ç pro┼Ťciej w taki spos├│b:

(4 >= 6 || "zielona" != "trawa") &&

   !(12 * 2 == 144 && true)

Nie zawsze jest oczywiste, czy nawiasy s─ů potrzebne. Zazwyczaj wystarczy tylko pami─Öta─ç, ┼╝e z operator├│w poznanych do tej pory najni┼╝szy priorytet ma ||, nast─Öpny jest &&, p├│┼║niej s─ů operatory por├│wnawcze (>, == itd.), a potem reszta. Priorytety operator├│w zosta┼éy tak dobrane, ┼╝e w prostych przypadkach mo┼╝na obej┼Ť─ç si─Ö z minimaln─ů ilo┼Ťci─ů nawias├│w.


We wszystkich przedstawionych do tej pory przyk┼éadach j─Özyk JavaScript by┼é u┼╝ywany w taki sam spos├│b, jak u┼╝ywa si─Ö kalkulatora kieszonkowego. Po prostu tworzone by┼éy okre┼Ťlone warto┼Ťci, na kt├│rych wykonywano dzia┼éania przy u┼╝yciu operator├│w. Tworzenie warto┼Ťci w ten spos├│b jest wa┼╝n─ů cz─Ö┼Ťci─ů ka┼╝dego programu JavaScript, ale nie jedyn─ů. Kod zwracaj─ůcy jak─ů┼Ť warto┼Ť─ç nazywa si─Ö wyra┼╝eniem. Wyra┼╝eniem jest ka┼╝da warto┼Ť─ç zapisana bezpo┼Ťrednio w kodzie (np. 22 albo "psychoanaliza"). To, co znajduje si─Ö w nawiasie r├│wnie┼╝ jest wyra┼╝eniem. Jest nim tak┼╝e operator dwuargumentowy zastosowany do dw├│ch wyra┼╝e┼ä jak i operator jednoargumentowy zastosowany do jednego wyra┼╝enia.

S─ů jeszcze inne sposoby tworzenia wyra┼╝e┼ä, ale poznasz je w stosownym czasie.

Istnieje te┼╝ jednostka programowa o szerszym zakresie ni┼╝ wyra┼╝enie. Jest to instrukcja. Program jest zestawem instrukcji. Wi─Ökszo┼Ť─ç z nich jest zako┼äczona ┼Ťrednikiem (;). Najprostsza instrukcja to wyra┼╝enie zako┼äczone ┼Ťrednikiem. To jest program:

1;
!false;

Program ten jest bezu┼╝yteczny. Wyra┼╝enie mo┼╝e by─ç jedynie tre┼Ťci─ů stanowi─ůc─ů jak─ů┼Ť warto┼Ť─ç, natomiast instrukcja ma sens tylko wtedy, gdy co┼Ť zmienia. Mo┼╝e np. drukowa─ç co┼Ť na ekranie — to liczy si─Ö jako zmiana czego┼Ť w otaczaj─ůcym ┼Ťwiecie — albo zmienia─ç wewn─Ötrzny stan programu, co spowoduje zmian─Ö dzia┼éania dalszych instrukcji. Zmiany te nazywaj─ů si─Ö „skutkami ubocznymi”. Instrukcje w powy┼╝szym przyk┼éadzie tworz─ů tylko warto┼Ťci 1 i true, a nast─Öpnie wrzucaj─ů je do wora z nieu┼╝ywanymi bitami5. Nie ma to ┼╝adnego wp┼éywu na otaczaj─ůcy je ┼Ťwiat i nie wywo┼éuje ┼╝adnych skutk├│w ubocznych.


Zmienne

W jaki spos├│b program utrzymuje sw├│j stan wewn─Ötrzny? Jak to si─Ö dzieje, ┼╝e r├│┼╝ne rzeczy s─ů przez niego pami─Ötane? Widzieli┼Ťmy ju┼╝ przyk┼éady tworzenia nowych warto┼Ťci z istniej─ůcych warto┼Ťci. Te operacje nie powodowa┼éy zmiany tych starych warto┼Ťci, a nowa warto┼Ť─ç musi zosta─ç od razu u┼╝yta, je┼Ťli nie chcemy, aby znikn─Ö┼éa. Dlatego do przechowywania warto┼Ťci w j─Özyku JavaScript u┼╝ywa si─Ö zmiennych.

var iloczyn = 5 * 5;

Zmienna musi mie─ç nazw─Ö i mo┼╝e wskazywa─ç jak─ů┼Ť warto┼Ť─ç. Powy┼╝sza instrukcja tworzy zmienn─ů o nazwie iloczyn i zapisuje w niej wynik mno┼╝enia 5 razy 5.

Gdy uruchomisz ten program, mo┼╝esz wpisa─ç w konsoli s┼éowo iloczyn, aby wy┼Ťwietli─ç warto┼Ť─ç 25. Nazwa zmiennej s┼éu┼╝y do pobierania reprezentowanej przez ni─ů warto┼Ťci. Mo┼╝na te┼╝ napisa─ç iloczyn + 1. Nazw zmiennych mo┼╝na u┼╝ywa─ç jako wyra┼╝e┼ä, a wi─Öc mog─ů one wchodzi─ç w sk┼éad tak┼╝e wi─Ökszych wyra┼╝e┼ä.

Do tworzenia zmiennych s┼éu┼╝y s┼éowo kluczowe var. Po nim nale┼╝y wpisa─ç nazw─Ö zmiennej. Jako nazwy zmiennej mo┼╝na u┼╝y─ç prawie ka┼╝dego s┼éowa. Nie mo┼╝na natomiast w nazwach zmiennych u┼╝ywa─ç spacji. Tak┼╝e cyfry s─ů dozwolone, np. iloczyn22, ale nie mog─ů znajdowa─ç si─Ö na pocz─ůtku. Znaki $ i _ r├│wnie┼╝ mog─ů wyst─Öpowa─ç w nazwach zmiennych i maj─ů w nich taki sam status, jak litery, a wi─Öc nazwa $_$ jest poprawna.

Je┼Ťli chcesz utworzonej zmiennej od razu przypisa─ç warto┼Ť─ç, co cz─Östo si─Ö robi, mo┼╝esz u┼╝y─ç operatora =, aby przypisa─ç jej warto┼Ť─ç jakiego┼Ť wyra┼╝enia.

Przypisanie zmiennej warto┼Ťci nie oznacza, ┼╝e musi tak pozosta─ç na zawsze. Warto┼Ť─ç istniej─ůcej zmiennej mo┼╝na w dowolnym momencie zmieni─ç za pomoc─ů operatora =.

iloczyn = 4 * 4;

Zmienne najlepiej jest wyobra┼╝a─ç sobie jako przyssawki, nie pude┼éka. Jest tak dlatego, poniewa┼╝ warto┼Ťci nie s─ů w nich przechowywane, a jedynie zmienne do tych warto┼Ťci si─Ö odwo┼éuj─ů ÔÇĽ nie ma przeszk├│d, aby dwie r├│┼╝ne zmienne odwo┼éywa┼éy si─Ö do tej samej warto┼Ťci. Program ma dost─Öp tylko do tych warto┼Ťci, do kt├│rych s─ů jakie┼Ť odwo┼éania. Gdy trzeba co┼Ť zapami─Öta─ç, przyczepia si─Ö do tego now─ů przyssawk─Ö albo odczepia si─Ö istniej─ůc─ů od czego┼Ť innego i przyczepia w nowym miejscu: aby zapami─Öta─ç, ile pieni─Ödzy winny jest Ci Lutek, mo┼╝esz napisa─çÔÇŽ

var dlugLutka = 140;

Gdy Lutek zwr├│ci cz─Ö┼Ť─ç tej kwoty, warto┼Ť─ç t─Ö mo┼╝na zmniejszy─ç przypisuj─ůc zmiennej now─ů liczb─Ö:

dlugLutka = dlugLutka - 35;

Zbi├│r zmiennych i ich warto┼Ťci w okre┼Ťlonym czasie nazywa si─Ö ┼Ťrodowiskiem. Nie jest ono puste podczas uruchamiania programu. Zawsze znajduje si─Ö w nim kilka standardowych zmiennych. Gdy przegl─ůdarka wczytuje stron─Ö, tworzy nowe ┼Ťrodowisko i dodaje do niego te standardowe zmienne. Zmienne tworzone i modyfikowane przez programy na tej stronie istniej─ů dop├│ki nie zostanie otwarta nowa strona.


Funkcje

Wiele warto┼Ťci dost─Öpnych w standardowym ┼Ťrodowisku jest typu funkcyjnego. Funkcja to fragment programu zapakowanego w warto┼Ťci. Zazwyczaj fragment ten robi co┼Ť po┼╝ytecznego i mo┼╝na go wywo┼éa─ç za pomoc─ů zawieraj─ůcej go warto┼Ťci. W ┼Ťrodowisku przegl─ůdarki istnieje zmienna alert przechowuj─ůca funkcj─Ö wy┼Ťwietlaj─ůc─ů ma┼ée okienko dialogowe z komunikatem. U┼╝ywa si─Ö jej nast─Öpuj─ůco:

alert("Awokado");

Wykonanie kodu funkcji nazywa si─Ö wywo┼éaniem funkcji. Do tego celu u┼╝ywa si─Ö nawiasu. Wywo┼éa─ç przy u┼╝yciu nawias├│w mo┼╝na ka┼╝de wyra┼╝enie tworz─ůce warto┼Ť─ç funkcyjn─ů. W powy┼╝szym przyk┼éadzie funkcji przekazano warto┼Ť─ç "Awokado", kt├│ra zosta┼éa wy┼Ťwietlona jako napis w oknie dialogowym. Warto┼Ťci przekazywane do funkcji nazywaj─ů si─Ö parametrami lub argumentami. Funkcja alert wymaga tylko jednego argumentu, ale s─ů funkcje, kt├│rym trzeba poda─ç wi─Öcej parametr├│w.


Wy┼Ťwietlenie okna dialogowego jest efektem ubocznym. Wiele funkcji jest przydatnych w┼éa┼Ťnie ze wzgl─Ödu na ich efekty uboczne. Funkcja mo┼╝e te┼╝ tworzy─ç warto┼Ť─ç i wtedy jest przydatna mimo ┼╝e nie ma skutku ubocznego. Istnieje np. funkcja o nazwie Math.max, kt├│ra przyjmuje dowoln─ů liczb─Ö warto┼Ťci liczbowych i zwraca najwi─Öksz─ů z nich:

alert(Math.max(2, 4));

Tworzenie warto┼Ťci przez funkcj─Ö nazywa si─Ö zwracaniem warto┼Ťci. Poniewa┼╝ w j─Özyku JavaScript warto┼Ťci s─ů zawsze tworzone przez wyra┼╝enia, wywo┼éa┼ä funkcji mo┼╝na u┼╝ywa─ç jako sk┼éadnik├│w wi─Ökszych wyra┼╝e┼ä:

alert(Math.min(2, 4) + 100);

Techniki tworzenia w┼éasnych funkcji s─ů opisane w rozdziale 3.


Jak pokaza┼éem w poprzednich przyk┼éadach, za pomoc─ů funkcji alert mo┼╝na wy┼Ťwietli─ç wynik jakiego┼Ť wyra┼╝enia. Chocia┼╝ te okienka, kt├│re trzeba zamyka─ç klikni─Öciem niejednego ju┼╝ doprowadzi┼éy do szewskiej pasji. Dlatego od tej pory b─Ödziemy u┼╝ywa─ç podobnej funkcji, o nazwie print, kt├│ra nie wy┼Ťwietla okna dialogowego, tylko drukuje warto┼Ť─ç w polu wyj┼Ťciowym konsoli. Funkcja print nie jest standardow─ů funkcj─ů JavaScript i nie jest normalnie obs┼éugiwana przez przegl─ůdarki, ale mo┼╝na jej u┼╝ywa─ç na stronach tego podr─Öcznika.

print("N");

Podobn─ů funkcj─ů r├│wnie┼╝ dost─Öpn─ů tylko na tych stronach jest show. Funkcja print drukuje sw├│j argument jako tekst, natomiast show pr├│buje zaprezentowa─ç go w taki spos├│b, jak wygl─ůda┼éby w programie, dzi─Öki czemu otrzymujemy wi─Öcej informacji na temat typu warto┼Ťci. Na przyk┼éad warto┼Ťci ┼éa┼äcuchowe przez funkcj─Ö show s─ů wy┼Ťwietlane wraz z cudzys┼éowami:

show("N");

W standardowym ┼Ťrodowisku przegl─ůdarek dost─Öpnych jest jeszcze kilka innych funkcji wy┼Ťwietlaj─ůcych wyskakuj─ůce okienka. Np. za pomoc─ů funkcji confirm mo┼╝na wy┼Ťwietli─ç okno, w kt├│rym u┼╝ytkownik musi klikn─ů─ç przycisk OK lub Anuluj jako odpowied┼║ na pytanie. Je┼Ťli u┼╝ytkownik kliknie przycisk OK, funkcja zwraca warto┼Ť─ç true, a je┼Ťli u┼╝ytkownik kliknie przycisk Anuluj, funkcja zwraca warto┼Ť─ç false.

show(confirm("Mo┼╝emy?"));

Funkcji prompt mo┼╝na u┼╝y─ç, aby zada─ç pytanie otwarte. Pierwszy argument zawiera pytanie, a drugi tekst, kt├│ry zostanie wst─Öpnie wy┼Ťwietlony w polu tekstowym na odpowied┼║. Gdy u┼╝ytkownik wpisze jaki┼Ť tekst w oknie, funkcja zwr├│ci go jako ┼éa┼äcuch.

show(prompt("Powiedz nam wszystko, co wiesz.", "..."));

Prawie ka┼╝dej zmiennej w ┼Ťrodowisku mo┼╝na nada─ç now─ů warto┼Ť─ç. Bywa to przydatne, ale i niebezpieczne. Je┼Ťli funkcji print przypisze si─Ö warto┼Ť─ç 8, to nie b─Ödzie mo┼╝na ju┼╝ nic przy jej u┼╝yciu wydrukowa─ç. Na szcz─Ö┼Ťcie w konsoli znajduje si─Ö du┼╝y przycisk Reset przywracaj─ůcy ┼Ťrodowisko do pierwotnego stanu.


Liniowe programy nie s─ů zbyt interesuj─ůce. Gdy program zawiera wi─Öcej ni┼╝ jedn─ů instrukcj─Ö, instrukcje te, jak nietrudno si─Ö domy┼Ťli─ç, s─ů wykonywane po kolei zaczynaj─ůc od g├│ry.

var liczba = Number(prompt("Wybierz liczb─Ö", ""));
print("Twoja liczba jest kwadratowym pierwiastkiem liczby " +
      (liczba * liczba));

Funkcja Number konwertuje warto┼Ť─ç na liczb─Ö, co w tym przypadku by┼éo konieczne, poniewa┼╝ funkcja prompt zwraca ┼éa┼äcuch. Istniej─ů te┼╝ funkcje o nazwach String i Boolean zamieniaj─ůce warto┼Ťci odpowiednio na ┼éa┼äcuchy i typ logiczny.


Spr├│bujmy napisa─ç program drukuj─ůcy wszystkie liczby parzyste z przedzia┼éu od 0 do 12. Oto jedna z mo┼╝liwo┼Ťci:

print(0);
print(2);
print(4);
print(6);
print(8);
print(10);
print(12);

To dzia┼éa, ale programy pisze si─Ö po to, aby zmniejszy─ç ilo┼Ť─ç pracy, a nie sobie jej doda─ç. Gdyby┼Ťmy chcieli wy┼Ťwietli─ç wszystkie parzyste liczby z przedzia┼éu do 100, to powy┼╝sza metoda by┼éaby niesamowicie pracoch┼éonna. Dlatego potrzebujemy jakiego┼Ť sposobu na wielokrotne wykonywanie kodu.

var biezacaLiczba = 0;
while (biezacaLiczba <= 12) {
  print(biezacaLiczba);
  biezacaLiczba = biezacaLiczba + 2;
}

Instrukcja while

Instrukcj─Ö while mog┼ée┼Ť ju┼╝ zauwa┼╝y─ç w rozdziale wst─Öpnym. Instrukcja zaczynaj─ůca si─Ö od s┼éowa while stanowi p─Ötl─Ö. P─Ötla zaburza normalny tok wykonywania instrukcji, poniewa┼╝ mo┼╝e zmusi─ç program do wykonania okre┼Ťlonego zestawu instrukcji wielokrotnie. W tym przypadku za s┼éowem while znajduje si─Ö wyra┼╝enie w nawiasie (nawias ten jest tu obowi─ůzkowy), kt├│re decyduje o tym, czy dzia┼éanie p─Ötli ma zosta─ç zako┼äczone, czy by─ç kontynuowane. Dop├│ki warto┼Ťci─ů logiczn─ů tego wyra┼╝enia jest true, p─Ötla powtarza wykonywanie zawartego w niej kodu. Gdy warto┼Ť─ç wyra┼╝enia logicznego zmieni si─Ö na false, nast─Öpuje przej┼Ťcie na d├│┼é p─Ötli i wykonywana jest dalsza cz─Ö┼Ť─ç programu w normalny spos├│b.

Zmienna biezacaLiczba demonstruje, w jaki spos├│b za pomoc─ů zmiennej mo┼╝na ┼Ťledzi─ç post─Öp wykonywania programu. W ka┼╝dym powt├│rzeniu p─Ötli warto┼Ť─ç tej zmiennej jest zwi─Ökszana o 2 i na pocz─ůtku ka┼╝dego powt├│rzenia warto┼Ť─ç ta jest por├│wnywana z liczb─ů 12, w celu okre┼Ťlenia, czy nale┼╝y wykona─ç nast─Öpne powt├│rzenie, czy nie.

Trzeci─ů cz─Ö┼Ťci─ů instrukcji while jest inna instrukcja. Stanowi ona tre┼Ť─ç w┼éa┼Ťciw─ů p─Ötli, czyli dzia┼éanie lub dzia┼éania, kt├│re maj─ů zosta─ç wykonane wielokrotnie. Gdyby┼Ťmy nie musieli drukowa─ç liczb, nasz program m├│g┼éby wygl─ůda─ç tak:

var biezacaLiczba = 0;
while (biezacaLiczba <= 12)
  biezacaLiczba = biezacaLiczba + 2;

W tym kodzie zasadnicz─ů tre┼Ť─ç p─Ötli stanowi instrukcja biezacaLiczba = biezacaLiczba + 2;. My musimy jednak wydrukowa─ç nasze liczby, a wi─Öc musimy u┼╝y─ç wi─Öcej ni┼╝ jednej instrukcji. Do grupowania instrukcji w bloki s┼éu┼╝─ů klamry ({ i }). Dla ┼Ťwiata zewn─Ötrznego blok jest pojedyncz─ů instrukcj─ů. We wcze┼Ťniejszym przyk┼éadzie w bloku znajduj─ů si─Ö wywo┼éanie funkcji print i instrukcja zmieniaj─ůca warto┼Ť─ç zmiennej biezacaLiczba.


─ćw. 2.2

Korzystaj─ůc z poznanych technik napisz program obliczaj─ůcy i wy┼Ťwietlaj─ůcy wynik dzia┼éania 210 (2 do pot─Ögi 10). Oczywi┼Ťcie nie mo┼╝esz stosowa─ç prymitywnych sztuczek w stylu 2 * 2 *...

Je┼Ťli masz problem z rozwi─ůzaniem tego zadania, dok┼éadnie przyjrzyj si─Ö przyk┼éadowi drukuj─ůcemu liczby parzyste. Ten program musi wykona─ç pewne dzia┼éanie okre┼Ťlon─ů liczb─Ö razy. Do jego budowy mo┼╝na u┼╝y─ç zmiennej licznikowej i p─Ötli while. Zamiast drukowa─ç licznik program musi pomno┼╝y─ç co┼Ť przez 2. Tym czym┼Ť powinna by─ç inna zmienna, w kt├│rej stopniowo gromadzony jest wynik.

Nie martw si─Ö, je┼Ťli jeszcze to do Ciebie nie przemawia. Nawet gdy doskonale zrozumiesz wszystkie opisywane w tym zagadnienia, mo┼╝esz mie─ç trudno┼Ťci z ich praktycznym wykorzystaniem. Umiej─Ötno┼Ť─ç pos┼éugiwania si─Ö kodem przychodzi wraz z praktyk─ů i dlatego przeanalizuj rozwi─ůzanie, a potem spr├│buj wykona─ç nast─Öpne ─çwiczenie.


─ćw. 2.3

Wprowadzaj─ůc drobne modyfikacje program napisany w poprzednim ─çwiczeniu mo┼╝na wykorzysta─ç do narysowania tr├│jk─ůta. Pod poj─Öciem „narysowa─ç tr├│jk─ůt” rozumiem oczywi┼Ťcie wydrukowanie tekstu w taki spos├│b, aby przypomina┼é t─Ö figur─Ö geometryczn─ů.

Wydrukujemy dziesi─Ö─ç linijek tekstu. W pierwszej b─Ödzie znajdowa─ç si─Ö tylko jeden znak #. W drugiej linijce b─Öd─ů dwa takie znaki itd.

Jak sprawi─ç, aby w linii zosta┼éo wydrukowanych X znak├│w #? Jednym ze sposob├│w jest utworzenie w ka┼╝dym powt├│rzeniu linii za pomoc─ů wewn─Ötrznej p─Ötli — tzn. p─Ötli znajduj─ůcej si─Ö w innej p─Ötli. Jednak pro┼Ťciej b─Ödzie utworzy─ç ┼éa┼äcuch i w ka┼╝dej iteracji dodawa─ç do niego po jednym znaku.


Zwr├│─ç uwag─Ö na odst─Öpy znajduj─ůce si─Ö przed niekt├│rymi instrukcjami. Nie s─ů one wymagane, tzn. dla komputera nie ma r├│┼╝nicy czy one s─ů, czy ich nie ma. W istocie nawet z┼éamania wierszy w programach nie s─ů obowi─ůzkowe. Je┼Ťli chcesz, ca┼éy program mo┼╝esz napisa─ç w jednym wierszu. Wci─Öcia w blokach kodu maj─ů za zadanie ukaza─ç struktur─Ö programu programi┼Ťcie czytaj─ůcemu kod. Poniewa┼╝ w istniej─ůcych blokach mo┼╝na tworzy─ç kolejne bloki, czasami mo┼╝e by─ç trudno zorientowa─ç si─Ö, gdzie ka┼╝dy blok si─Ö rozpoczyna i ko┼äczy, zw┼éaszcza w skomplikowanych programach. Gdy zastosowane s─ů wci─Öcia, program wizualnie odzwierciedla struktur─Ö blok├│w, z kt├│rych jest zbudowany. Ja dla ka┼╝dego nowego bloku stosuj─Ö wci─Öcie na g┼é─Öboko┼Ť─ç dw├│ch spacji, ale s─ů r├│┼╝ne gusta.

Pole w konsoli do wprowadzania kodu program├│w dodaje odst─Öpy automatycznie. Pocz─ůtkowo mo┼╝e Ci─Ö to denerwowa─ç, ale gdy napiszesz wi─Öksz─ů ilo┼Ť─ç kodu, docenisz jak du┼╝o czasu mo┼╝na dzi─Öki temu zaoszcz─Ödzi─ç. Naciskaj─ůc klawisz Tab mo┼╝na zwi─Ökszy─ç wci─Öcie wiersza, w kt├│rym znajduje si─Ö kursor.

W pewnych szczeg├│lnych przypadkach w j─Özyku JavaScript dopuszczalne jest opuszczenie ┼Ťrednika na ko┼äcu instrukcji. W innych sytuacjach ┼Ťrednik koniecznie musi by─ç u┼╝yty albo dziej─ů si─Ö dziwne rzeczy. Regu┼éy dotycz─ůce tego, kiedy mo┼╝na opu┼Ťci─ç ┼Ťrednik s─ů zawi┼ée i dziwaczne. W tym podr─Öczniku nie opu┼Ťci┼éem ani jednego ┼Ťrednika i zach─Öcam Ci─Ö, aby┼Ť robi┼é tak samo.


Wszystkie przedstawione do tej pory przyk┼éady u┼╝ycia instrukcji while s─ů zbudowane wg jednej zasady. Najpierw tworzona jest zmienna reprezentuj─ůca licznik. Za jej pomoc─ů ┼Ťledzony jest post─Öp wykonywania programu. Instrukcja while sama zawiera test, kt├│ry najcz─Ö┼Ťciej polega na sprawdzeniu, czy licznik osi─ůgn─ů┼é okre┼Ťlon─ů warto┼Ť─ç. Nast─Öpnie na ko┼äcu w┼éa┼Ťciwej tre┼Ťci p─Ötli nast─Öpuje zwi─Ökszenie warto┼Ťci licznika.

W ten sposób można napisać wiele różnych pętli. Dlatego w języku JavaScript, i wielu innych językach, dostępna jest nieco bardziej zwięzła postać pętli:

for (var liczba = 0; liczba <= 12; liczba = liczba + 2)
  show(liczba);

Ten program zwr├│ci dok┼éadnie taki sam wynik, jak pokazany wcze┼Ťniej program drukuj─ůcy liczby parzyste. Jedyna r├│┼╝nica mi─Ödzy tymi dwiema p─Ötlami polega na tym, ┼╝e w tym przypadku wszystkie instrukcje dotycz─ůce „stanu” p─Ötli znajduj─ů si─Ö w jednym wierszu. W nawiasie znajduj─ůcym si─Ö za s┼éowem for powinny znajdowa─ç si─Ö dwa ┼Ťredniki. Kod znajduj─ůcy si─Ö przed pierwszym ┼Ťrednikiem inicjuje p─Ötl─Ö i zazwyczaj zawiera definicj─Ö zmiennej. Druga cz─Ö┼Ť─ç jest wyra┼╝eniem sprawdzaj─ůcym, czy wykonywanie p─Ötli powinno by─ç kontynuowane. Ostatnia cz─Ö┼Ť─ç aktualizuje stan p─Ötli. W wi─Ökszo┼Ťci przypadk├│w ten rodzaj p─Ötli jest bardziej zwi─Öz┼éy i prostszy od konstrukcji while.


W nazwach niekt├│rych zmiennych mo┼╝na zauwa┼╝y─ç dziwny spos├│b u┼╝ycia wielkich liter. Przypomn─Ö, ┼╝e nazwy zmiennych nie mog─ů zawiera─ç spacji, poniewa┼╝ komputer traktowa┼éby je jako kilka oddzielnych s┼é├│w, i dlatego nazwy sk┼éadaj─ůce si─Ö z kilku s┼é├│w trzeba zapisywa─ç na r├│┼╝ne inne sposoby: malyfiglarnykonik, maly_figlarny_konik, Ma┼éyFiglarnyKonik lub malyFiglarnyKonik. Pierwsza wersja jest trudna do odczytania. Podoba mi si─Ö wersja ze znakami podkre┼Ťlenia, ale ich wpisywanie jest k┼éopotliwe. Nazwy standardowych funkcji j─Özyka JavaScript s─ů pisane przy u┼╝yciu ostatniej metody, z kt├│rej korzysta te┼╝ wielu programist├│w. Nietrudno jest si─Ö do tego przyzwyczai─ç i dlatego b─Öd─Ö post─Öpowa┼é jak inni, czyli b─Öd─ů zapisywa┼é z wielkiej litery wszystkie s┼éowa w nazwach opr├│cz pierwszego.

Istnieje te┼╝ kilka przypadk├│w, jak nazwa funkcji Number, w kt├│rych wielka jest te┼╝ litera pierwszego s┼éowa. Umownie oznacza to, ┼╝e funkcja ta jest konstruktorem. Czym s─ů konstruktory dowiesz si─Ö w rozdziale 8. Na razie po prostu ignoruj ten pozorny brak konsekwencji.

Pami─Ötaj te┼╝, ┼╝e niekt├│re s┼éowa, np. var, while i for, maj─ů w j─Özyku specjalne znaczenie i nie mo┼╝na ich u┼╝ywa─ç do nazywania zmiennych. S─ů to tzw. s┼éowa kluczowe. Istnieje te┼╝ grupa s┼é├│w zarezerwowanych do u┼╝ytku przez JavaScript w przysz┼éo┼Ťci. Oficjalnie ich r├│wnie┼╝ nie mo┼╝na u┼╝ywa─ç jako nazw zmiennych, chocia┼╝ niekt├│re przegl─ůdarki tego nie przestrzegaj─ů. Oto lista wszystkich s┼é├│w tego rodzaju:

abstract boolean break byte case catch char class const continue
debugger default delete do double else enum export extends false
final finally float for function goto if implements import in
instanceof int interface long native new null package private
protected public return short static super switch synchronized
this throw throws transient true try typeof var void volatile
while with

Nie m─Öcz si─Ö, aby je wszystkie od razu zapami─Öta─ç. Wystarczy ┼╝e sobie o nich przypomnisz, gdy Tw├│j program nie b─Ödzie dzia┼éa┼é zgodnie z Twoimi oczekiwaniami. Z mojego do┼Ťwiadczenia wynika, ┼╝e najcz─Ö┼Ťciej u┼╝ywanymi niedozwolonymi nazwami s─ů s┼éowa char (do przechowywania pojedynczego znaku) i class.


─ćw. 2.4

Przepisz poprzednie przykłady użycia pętli while przy użyciu pętli for.


W programach cz─Östo zmienia si─Ö warto┼Ťci zmiennych na warto┼Ťci b─Öd─ůce modyfikacj─ů ich poprzednich warto┼Ťci. Na przyk┼éad licznik = licznik + 1. W j─Özyku JavaScript istnieje mo┼╝liwo┼Ť─ç wyra┼╝enia tego w skr├│cony spos├│b: licznik += 1. Technik─Ö te mo┼╝na stosowa─ç tak┼╝e z wieloma innymi operatorami, np. wynik *= 2 podwaja warto┼Ť─ç zmiennej wynik, a licznik -= 1 zmniejsza warto┼Ť─ç licznika.

Konstrukcje licznik += 1 i licznik -= 1 mo┼╝na nawet zapisa─ç jeszcze kr├│cej: licznik++ i licznik--.


Instrukcja for

M├│wi si─Ö, ┼╝e p─Ötle zmieniaj─ů przep┼éyw sterowania w programie. Zmieniaj─ů kolejno┼Ť─ç wykonywania instrukcji. W wielu przypadkach potrzebna jest te┼╝ zmiana przep┼éywu w inny spos├│b: poprzez pomijanie instrukcji.

Wyobra┼║ sobie, ┼╝e chcesz wy┼Ťwietli─ç wszystkie liczby mniejsze od 20, kt├│re s─ů podzielne zar├│wno przez 3, jak i 4.

for (var licznik = 0; licznik < 20; licznik++) {
  if (licznik % 3 == 0 && licznik % 4 == 0)
    show(licznik);
}

S┼éowo kluczowe if dzia┼éa bardzo podobnie do s┼éowa while: sprawdza warunek podany w nawiasie i podejmuje decyzj─Ö czy wykona─ç instrukcj─Ö w zale┼╝no┼Ťci od warto┼Ťci tego warunku. Robi to jednak tylko raz, a wi─Öc instrukcja mo┼╝e zosta─ç wykonana zero razy lub jeden raz.

Sztuczka z operatorem reszty z dzielenia (%) pozwala w ┼éatwy spos├│b sprawdzi─ç czy jedna liczba dzieli si─Ö bez reszty przez inn─ů. Je┼Ťli tak, to reszta z dzielenia zwr├│cona przez ten operator wynosi zero.

Gdyby┼Ťmy chcieli wy┼Ťwietli─ç wszystkie liczby z przedzia┼éu do 20, a podzielne przez 4 umie┼Ťci─ç w nawiasach, mogliby┼Ťmy napisa─ç taki kod:

for (var licznik = 0; licznik < 20; licznik++) {
  if (licznik % 4 == 0)
    print(licznik);
  if (licznik % 4 != 0)
    print("(" + licznik + ")");
}

Teraz jednak program musi sprawdzi─ç czy warto┼Ť─ç zmiennej licznik jest podzielna przez 4 dwa razy. Ten sam efekt mo┼╝na uzyska─ç dodaj─ůc instrukcj─Ö else za instrukcj─ů if. Instrukcja elsejest wykonywana tylko wtedy, gdy warto┼Ť─ç warunku instrukcji if jest fa┼észywa.

for (var licznik = 0; licznik < 20; licznik++) {
  if (licznik % 4 == 0)
    print(licznik);
  else
    print("(" + licznik + ")");
}

Ten przykład jest banalny, ale możemy go trochę skomplikować. Spróbujemy wydrukować te same liczby, ale po każdej większej od 15 dodamy dwie gwiazdki, po każdej większej od 10 i mniejszej od 15 dodamy po jednej gwiazdce, a do pozostałych nic nie będziemy dodawać.

for (var licznik = 0; licznik < 20; licznik++) {
  if (licznik > 15)
    print(licznik + "**");
  else if (licznik > 10)
    print(licznik + "*");
  else
    print(licznik);
}

Jak wida─ç w powy┼╝szym kodzie, instrukcje if mo┼╝na ┼é─ůczy─ç w ┼éa┼äcuchy. ten program najpierw sprawdza czy warto┼Ť─ç zmiennej licznik jest wi─Öksza od 15. Je┼Ťli tak, nast─Öpuje wydruk dw├│ch gwiazdek, a pozosta┼ée testy s─ů pomijane. Je┼Ťli nie, program sprawdza czy warto┼Ť─ç zmiennej licznik jest wi─Öksza od 10. Je┼Ťli warto┼Ť─ç zmiennej licznik nie jest wi─Öksza od 10, nast─Öpuje wykonanie ostatniej instrukcji print.


─ćw. 2.5

Napisz program pytaj─ůcy za pomoc─ů instrukcji prompt, ile wynosi 2 + 2. Je┼Ťli zostanie udzielona odpowied┼║ 4, wy┼Ťwietl jak─ů┼Ť pochwal─Ö przy u┼╝yciu instrukcji alert. Je┼Ťli zostanie wpisana liczba 3 albo 5, wy┼Ťwietl napis „Prawie!”. W pozosta┼éych przypadkach wydrukuj co┼Ť nieprzyjemnego.


Je┼Ťli nie ma potrzeby, aby wszystkie instrukcje p─Ötli by┼éy wykonywane do samego ko┼äca, mo┼╝na pos┼éu┼╝y─ç si─Ö s┼éowem kluczowym break. Powoduje ono natychmiastowe wyj┼Ťcie z bie┼╝─ůcej p─Ötli i kontynuowanie wykonywania programu za ni─ů. Ten program znajduje pierwsz─ů liczb─Ö wi─Öksz─ů od 20 i podzieln─ů przez 7:

for (var biezaca = 20; ; biezaca++) {
  if (biezaca % 7 == 0)
    break;
}
print(biezaca);

W powy┼╝szej instrukcji for brakuje warunku pozwalaj─ůcego zako┼äczy─ç jej dzia┼éanie. Z tego powodu zako┼äczenie wykonywania tej p─Ötli mo┼╝e nast─ůpi─ç wy┼é─ůcznie dzi─Öki instrukcji break. Ten sam program mo┼╝na by by┼éo r├│wnie┼╝ zapisa─ç tak:

for (var biezaca = 20; biezaca % 7 != 0; biezaca++)
  ;
print(biezaca);

W tym przypadku tre┼Ť─ç p─Ötli jest pusta. Za pomoc─ů samego ┼Ťrednika mo┼╝na utworzy─ç pust─ů instrukcj─Ö. Jedynym skutkiem dzia┼éania tej p─Ötli jest zwi─Ökszenie warto┼Ťci zmiennej biezaca do ┼╝─ůdanego poziomu. Potrzebny by┼é mi jednak te┼╝ przyk┼éad z u┼╝yciem instrukcji break, a wi─Öc dobrze przyjrzyj si─Ö te┼╝ poprzedniej wersji.


─ćw. 2.6

Do rozwi─ůzania poprzedniego ─çwiczenia dodaj instrukcj─Ö while i ewentualnie break, aby pytanie by┼éo wy┼Ťwietlane, a┼╝ w ko┼äcu zostanie podana prawid┼éowa odpowied┼║.

P─Ötl─Ö, kt├│ra nigdy nie zako┼äczy dzia┼éania sama mo┼╝na utworzy─ç pisz─ůc while (true) .... Mo┼╝e si─Ö to wydawa─ç troch─Ö g┼éupie, ┼╝e nakazujemy programowi wykonywa─ç instrukcje dop├│ki true jest true, ale to naprawd─Ö bardzo przydatna sztuczka.


W rozwi─ůzaniu poprzedniego ─çwiczenia znalaz┼éa si─Ö instrukcja var odpowiedz;. Tworzy ona zmienn─ů o nazwie odpowiedz, ale nie nadaje jej ┼╝adnej warto┼Ťci. Co si─Ö stanie, gdy spr├│bujemy u┼╝y─ç warto┼Ťci tej zmiennej?

var tajemniczaZmienna;
show(tajemniczaZmienna);

Pos┼éuguj─ůc si─Ö metafor─ů przyssawek, mo┼╝na powiedzie─ç, ┼╝e ta zmienna nie jest do niczego przyssana. Gdy spr├│bujesz u┼╝y─ç warto┼Ťci pustego miejsca, otrzymasz specjaln─ů warto┼Ť─ç o nazwie undefined. Tak┼╝e funkcje nie zwracaj─ůce ┼╝adnej sensownej warto┼Ťci, takie jak np. print i alert, zwracaj─ů warto┼Ť─ç undefined.

show(alert("Jestem skutkiem ubocznym."));

Istnieje te┼╝ podobna warto┼Ť─ç null, kt├│ra oznacza, ┼╝e „dana zmienna jest zdefiniowana, ale nie ma ┼╝adnej warto┼Ťci”. R├│┼╝nica znaczenia mi─Ödzy warto┼Ťciami undefined i null ma przede wszystkim znaczenie naukowe i nie jest zbyt ciekawa. W praktyce zwykle sprawdza si─Ö, czy co┼Ť „ma warto┼Ť─ç”. W takich przypadkach mo┼╝na u┼╝ywa─ç wyra┼╝e┼ä typu cokolwiek == undefined, poniewa┼╝, mimo ┼╝e warto┼Ťci te nie s─ů tym samym, wyra┼╝enie null == undefined ma warto┼Ť─ç true.


To prowadzi nas do kolejnego ciekawego tematu…

show(false == 0);
show("" == 0);
show("5" == 5);

Wszystkie te instrukcje zwracaj─ů warto┼Ť─ç true. Do por├│wnywania warto┼Ťci r├│┼╝nych typ├│w JavaScript stosuje skomplikowane i niejasne regu┼éy. Nie b─Öd─Ö nawet pr├│bowa┼é ich dok┼éadnie wyja┼Ťni─ç, ale najpro┼Ťciej mo┼╝na powiedzie─ç, ┼╝e zazwyczaj pr├│buje przekonwertowa─ç jedn─ů z warto┼Ťci na typ drugiej. Je┼Ťli jednak z kt├│rej┼Ť strony wyst─ůpi warto┼Ť─ç null lub undefined, warto┼Ť─ç true jest zwracana tylko wtedy, gdy z obu stron znajduje si─Ö null lub undefined.

Jak w takim razie sprawdzi─ç, czy wybrana zmienna odnosi si─Ö do warto┼Ťci false? Zgodnie z regu┼éami konwersji ┼éa┼äcuch├│w i liczb na warto┼Ťci logiczne 0 i pusty ┼éa┼äcuch s─ů traktowane jako false, natomiast wszystkie pozosta┼ée warto┼Ťci oznaczaj─ů true. Z tego wzgl─Ödu warto┼Ťci─ů wyra┼╝enia zmienna == false jest true, gdy zmienna odwo┼éuje si─Ö do 0 lub "". Je┼Ťli nie chcesz, aby ta automatyczna konwersja typ├│w by┼éa wykonywana, mo┼╝esz u┼╝y─ç jednego z dw├│ch dodatkowych operator├│w: === i !==. Pierwszy sprawdza czy dana warto┼Ť─ç jest identyczna z drug─ů, natomiast drugi — czy dana warto┼Ť─ç jest dok┼éadnie r├│┼╝na od drugiej.

show(null === undefined);
show(false === 0);
show("" === 0);
show("5" === 5);

Wszystkie te instrukcje zwr├│c─ů warto┼Ť─ç false.


Warto┼Ťci u┼╝ywane w warunkach w instrukcjach if, while oraz for nie musz─ů by─ç logiczne. Przed sprawdzeniem zostan─ů automatycznie przekonwertowane na ten typ. Oznacza to, ┼╝e liczba 0, pusty ┼éa┼äcuch "", null, undefined i oczywi┼Ťcie false zostan─ů potraktowane jako fa┼ész.

Wykorzystuj─ůc fakt, ┼╝e wszystkie pozosta┼ée warto┼Ťci zostan─ů zamienione na warto┼Ť─ç true w wielu przypadkach mo┼╝na opu┼Ťci─ç bezpo┼Ťrednie por├│wnywanie. Je┼Ťli wiadomo, ┼╝e zmienna mo┼╝e zawiera─ç tylko albo ┼éa┼äcuch albo warto┼Ť─ç null, mo┼╝na j─ů bardzo ┼éatwo testowa─çÔÇŽ

var mozeNull = null;
// ÔÇŽtajemniczy kod, kt├│ry mo┼╝e zapisa─ç ┼éa┼äcuch w zmiennej mozeNullÔÇŽ
if (mozeNull)
  print("Zmienna mozeNull ma warto┼Ť─ç");

Wyj─ůtkiem jest sytuacja, w kt├│rej tajemniczy kod przypisze zmiennej mozeNull warto┼Ť─ç "". Pusty ┼éa┼äcuch jest r├│wnoznaczny z fa┼észem, a wi─Öc w tym przypadku nic nie zostanie wydrukowane. W niekt├│rych przypadkach mo┼╝e to by─ç b┼é─ůd. Tego subtelnego b┼é─Ödu mo┼╝na unikn─ů─ç u┼╝ywaj─ůc por├│wnania === null lub === false. To samo dotyczy warto┼Ťci liczbowych, kt├│re mog─ů wynosi─ç 0.


Wiersz zawieraj─ůcy opis tajemniczego kodu w powy┼╝szym przyk┼éadzie mo┼╝e wyda─ç Ci si─Ö troch─Ö podejrzany. Dodatkowe obja┼Ťnienia w kodzie program├│w s─ů cz─Östo bardzo przydatne. Zazwyczaj stosuje si─Ö je, aby wyja┼Ťni─ç ludzkim j─Özykiem, co robi dany fragment programu.

// Licznik zmiennej, którego definicja znajduje się poniżej, będzie miał
// warto┼Ť─ç pocz─ůtkow─ů 0, czyli zero.
var licznik = 0;
// Teraz rozpoczynamy p─Ötl─Ö, wi─Öc dobrze si─Ö trzymaj.
while (licznik < 100 /* Licznik ma warto┼Ť─ç mniejsz─ů od stu */)
/* W ka┼╝dym powt├│rzeniu p─Ötli ZWI─śKSZAMY warto┼Ť─ç licznika
   Dodajemy do niej jeden */
  licznik++;
// Koniec.

Tego rodzaju teksty nazywaj─ů si─Ö komentarzami. Oto regu┼éy ich stosowania: 'ci─ůg /* stanowi pocz─ůtek komentarza, kt├│ry ko┼äczy si─Ö ci─ůgiem */. 'Ci─ůg // r├│wnie┼╝ oznacza pocz─ůtek komentarza, ale jego koniec wyznacza koniec wiersza.

Jak wida─ç, dzi─Öki komentarzom mo┼╝na sprawi─ç, ┼╝e nawet najprostszy program b─Ödzie wygl─ůda┼é jakby by┼é du┼╝y, brzydki i niesamowicie skomplikowany.


S─ů jeszcze inne sytuacje, w kt├│rych mo┼╝e doj┼Ť─ç do automatycznej konwersji typ├│w. Gdy do ┼éa┼äcucha doda si─Ö warto┼Ť─ç nieb─Öd─ůc─ů ┼éa┼äcuchem, warto┼Ť─ç ta przed do┼é─ůczeniem zostanie przekszta┼écona w ┼éa┼äcuch. Je┼Ťli pomno┼╝ymy liczb─Ö przez ┼éa┼äcuch, JavaScript spr├│buje przed wykonaniem dzia┼éania zamieni─ç ten ┼éa┼äcuch na liczb─Ö.

show("Apollo" + 5);
show(null + "ify");
show("5" * 5);
show("truskawka" * 5);

Ostatnia instrukcja spowodowa┼éa wydrukowanie napisu NaN, kt├│ry oznacza specjaln─ů warto┼Ť─ç. Jest to skr├│t od angielskich s┼é├│w „Not a Number” (nie liczba) i co ciekawe, jest to typ liczbowy. W tym przypadku dowiadujemy si─Ö, ┼╝e truskawka nie jest liczb─ů. Wynikiem wszystkich dzia┼éa┼ä arytmetycznych na warto┼Ťci NaN jest NaN i dlatego w┼éa┼Ťnie w wyniku mno┼╝enia przez 5 otrzymali┼Ťmy NaN. Ponadto zapewne zaskoczy Ci─Ö fakt, ┼╝e wynikiem por├│wnania NaN == NaN jest false. Do sprawdzania czy dana warto┼Ť─ç jest NaN mo┼╝na u┼╝ywa─ç funkcji isNaN. NaN to kolejna (i ju┼╝ ostatnia) warto┼Ť─ç, kt├│ra w wyniku konwersji na typ logiczny zamienia si─Ö w false.

Te automatyczne konwersje bywaj─ů naprawd─Ö wygodne, ale zasady ich wykonywania s─ů dziwaczne i stanowi─ů ┼║r├│d┼éo wielu b┼é─Öd├│w. Mimo ┼╝e + i * to operatory arytmetyczne, w tym przyk┼éadzie oba zachowuj─ů si─Ö ca┼ékiem inaczej. We w┼éasnych programach cz─Östo u┼╝ywam operatora + do ┼é─ůczenia ┼éa┼äcuch├│w i „nie┼éa┼äcuch├│w”, ale operatora * i innych operator├│w arytmetycznych lepiej na ┼éa┼äcuchach nie u┼╝ywa─ç. Konwersja liczby na ┼éa┼äcuch zawsze jest mo┼╝liwa i ┼éatwa, natomiast zamiana ┼éa┼äcucha w liczb─Ö mo┼╝e si─Ö nie uda─ç (tak jak w ostatnim wierszu kodu w przytoczonym przyk┼éadzie). Aby jawnie przekonwertowa─ç ┼éa┼äcuch na liczb─Ö, mo┼╝na u┼╝y─ç funkcji Number i w├│wczas o┼Ťwiadczamy, ┼╝e jeste┼Ťmy ┼Ťwiadomi ryzyka otrzymania warto┼Ťci NaN.

show(Number("5") * 5);

W cz─Ö┼Ťci po┼Ťwi─Öconej operatorom logicznym && i || napisa┼éem, ┼╝e operatory te tworz─ů warto┼Ťci logiczne. Musz─Ö przyzna─ç, ┼╝e to by┼éo uproszczenie. Je┼Ťli zastosuje si─Ö je do warto┼Ťci logicznych, to rzeczywi┼Ťcie zwr├│c─ů warto┼Ť─ç logiczn─ů. Ale mo┼╝na je stosowa─ç tak┼╝e do innych typ├│w danych i w├│wczas zwracaj─ů jeden ze swoich argument├│w.

Operator || tak naprawd─Ö najpierw sprawdza warto┼Ť─ç znajduj─ůc─ů si─Ö po jego lewej stronie. Je┼Ťli w wyniku konwersji tej warto┼Ťci na typ logiczny otrzyma true, zwraca t─Ö warto┼Ť─ç znajduj─ůc─ů si─Ö po jego lewej stronie. W przeciwnym przypadku zwraca warto┼Ť─ç znajduj─ůc─ů si─Ö po prawej. Mo┼╝esz to sam sprawdzi─ç. Dlaczego tak jest? Jest to przydatne w praktyce. Rozwa┼╝my poni┼╝szy przyk┼éad:

var input = prompt("Jak si─Ö nazywasz?", "Kilgore Trout");
print("No to cze┼Ť─ç, " + (input || "┼╝abko"));

Je┼Ťli u┼╝ytkownik naci┼Ťnie przycisk Anuluj albo zamknie okno dialogowe prompt w jaki┼Ť inny spos├│b bez podawania swojego nazwiska, zmienna input b─Ödzie mia┼éa warto┼Ť─ç null lub "". Obie te warto┼Ťci po przekonwertowaniu na typ logiczny da┼éyby false. Wyra┼╝enie input || "┼╝abko" mo┼╝na w tym przypadku przeczyta─ç nast─Öpuj─ůco: „warto┼Ť─ç zmiennej input lub ┼éa┼äcuch "┼╝abko"”. Jest to ┼éatwy spos├│b na zdefiniowanie warto┼Ťci „awaryjnej”.

Operator && dzia┼éa wg podobnych zasad, tylko odwrotnie. Gdy po jego lewej stronie znajduje si─Ö warto┼Ť─ç daj─ůca false po konwersji na typ logiczny, zwraca t─Ö warto┼Ť─ç. W przeciwnym przypadku zwraca warto┼Ť─ç znajduj─ůc─ů si─Ö po prawej.

Kolejn─ů ciekaw─ů w┼éa┼Ťciwo┼Ťci─ů tych operator├│w jest to, ┼╝e wyra┼╝enie znajduj─ůce si─Ö po prawej stronie jest obliczane tylko wtedy, gdy jest to konieczne. W przypadku true || X nie ma znaczenia, jaka jest warto┼Ť─ç X, poniewa┼╝ wynik zawsze b─Ödzie true, a wi─Öc warto┼Ť─ç X nigdy nie b─Ödzie obliczana. A je┼Ťli to wyra┼╝enie mia┼éoby jakie┼Ť skutki uboczne, to nigdy by┼Ťmy ich nie zaobserwowali. To samo dotyczy wyra┼╝enia false && X.

false || alert("Niech si─Ö dzieje!");
true || alert("Nic si─Ö nie dzieje.");

Przypisy

  1. Bit to dowolny byt mog─ůcy mie─ç jedn─ů z dw├│ch warto┼Ťci, kt├│re zazwyczaj opisuje si─Ö jako 0 i 1. W komputerze warto┼Ťci te s─ů reprezentowane przez wysok─ů i nisk─ů warto┼Ť─ç ┼éadunku elektrycznego, silny i s┼éaby sygna┼é albo l┼Ťni─ůc─ů lub matow─ů powierzchni─Ö na p┼éycie CD.
  2. Je┼Ťli spodziewa┼ée┼Ť si─Ö tu zobaczy─ç warto┼Ť─ç 10010000, to dobrze my┼Ťlisz. W JavaScripcie liczby nie s─ů jednak przechowywane jako liczby ca┼ékowite.
  3. Tak naprawd─Ö to 53, poniewa┼╝ stosowana jest sztuczka pozwalaj─ůca uzyska─ç jeden dodatkowy bit. Je┼Ťli interesuj─ů Ci─Ö szczeg├│┼éy, zajrzyj do standardu IEEE 754.
  4. Gdy wpiszesz warto┼Ťci ┼éa┼äcuchowe w konsoli, zostan─ů one zwr├│cone z cudzys┼éowami i uko┼Ťnikami, dok┼éadnie tak, jak zosta┼éy wpisane. Aby poprawnie wy┼Ťwietli─ç specjalne znaki, mo┼╝na napisa─ç print("anb") ÔÇĽ wkr├│tce wyja┼Ťni─Ö, dlaczego tak jest.
  5. W├│r na bity to miejsce, w kt├│rym przechowywane s─ů stare bity. W niekt├│rych systemach programista musi w┼éasnor─Öcznie go od czasu do czasu opr├│┼╝nia─ç. Na szcz─Ö┼Ťcie w JavaScripcie odzyskiwanie zasob├│w odbywa si─Ö w pe┼éni automatycznie.

Autor: Marijn Haverbeke

Źródło: http://eloquentjavascript.net/1st_edition/chapter2.html

Tłumaczenie: Łukasz Piwko

Tre┼Ť─ç tej strony jest dost─Öpna na zasadach licencji CC BY 3.0

5 komentarzy do “Rozdzia┼é 2. Podstawy JavaScriptu. Warto┼Ťci, zmienne i kontrola sterowania”

  1. W ─çwiczeniu 2.2 jest b┼é─ůd. „napisz program obliczaj─ůcy i wy┼Ťwietlaj─ůcy wynik dzia┼éania 210 (2 do pot─Ögi 10).” Powinno by─ç 1024 a nie 210.

  2. W przyk┼éadach opisuj─ůcych dzia┼éanie p─Ötli for jest b┼é─ůd. W wyja┼Ťnieniu jest, ┼╝e kod ma wy┼Ťwietla─ç liczby podzielne przez 4 w nawiasie, a wykonuje si─Ö, ┼╝e wszystkie inne s─ů w nawiasie, a podzielne przez 4 nie.
    Pozdrawiam.

    Bardzo podoba mi si─Ö Wasz kurs

  3. Swietne tlumaczenie!
    Drobna uwaga na temat funkcjonalnosci: jesli od przypisow moznaby bylo powrocic dokladnie do tego punktu, gdzie znajdowal sie odnosnik do przypisu, znaczynie ulatwiloby to plynne czytanie tekstu. Szukanie miejsca w ktorym sie zaprzestalo czytac zdecydowanie obniza koncentracje. Pozdrawiam.

  4. hey,

    w opisie funkcji alert jest b┼é─ůd – „Warto┼Ťci przekazywane do funkcji nazywaj─ů si─Ö parametrami lub argumentami”.

    Mianowicie warto┼Ťci przekazywane do funkcji podczas jej wywo┼éania to s─ů argumenty.
    Parametry s─ů natomiast cz─Ö┼Ťci─ů deklaracji funckji :).

    Pozdrawiam

Mo┼╝liwo┼Ť─ç komentowania zosta┼éa wy┼é─ůczona.