forked from max-mapper/javascript-for-cats
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
358 lines (343 loc) · 36.6 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<title>JavaScript dla kotów</title>
<link rel="stylesheet" href="stylesheets/style.css">
<link rel="stylesheet" href="stylesheets/rainbow.github.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<meta property="og:url" content="http://jsforcats.m4sk.in">
<meta property="og:type" content="website">
<meta property="og:title" content="JavaScript dla kotów">
<meta property="og:description" content="Wprowadzenie dla początkujących programistów dedykowane kotom.">
<meta property="og:image" content="images/substack-cats.png">
<meta property="og:image:type" content="image/png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="675">
</head>
<body>
<div id="container">
<div id="main">
<div id="post" class="sticky-menu">
<div class="inner clearfix">
<div class="document prose">
<div class="surface preview">
<div class="content-preview-wrapper">
<div class="content-preview">
<div class="post-content" style="white-space: normal;">
<p><span class="bigTitle">JavaScript dla kotów</span></p>
<h2 id="wprowadzenie-dla-pocz-tkuj-cych-programist-w-span-class-right-cat-images-substack-cats-png-span-">Wprowadzenie dla początkujących programistów <span class="right"><img src="images/substack-cats.png" alt="cat"></span></h2>
<h3 id="-tak-proste-e-nawet-tw-j-ludzki-towarzysz-da-by-rad-"><em>Tak proste, że nawet twój ludzki towarzysz dałby radę!</em></h3>
<p>JavaScript jest językiem programowania, czyli innymi słowy językiem, którym instruujesz komputer, co ma robić. Tak, jak kontrolujesz człowieka używając syczenia i miauczenia, tak komputer jest kontrolowany z użyciem instrukcji w języku programowania. Wszystkie współczesne przeglądarki internetowe obsługują JavaScript, więc możesz wykorzystać jego możliwości do naprawdę szalonych rzeczy!</p>
<p>JavaScript powstał, aby uczynić strony internetowe bardziej interaktywnymi. Obecnie jest używany nie tylko w przeglądarkach, ale także na serwerach, smartfonach, a nawet robotach! Ta strona nauczy cię podstaw JavaScript bez zabierania zbędnego czasu*, więc szybciej zaczniesz działać.</p>
<p>* <em>W praktyce: trochę więcej. Zapewne godzinę lub dwie. Pamiętaj, że będąc kotem wolisz raczej leżeć w słońcu niż biegać…</em></p>
<p>JavaScript dla kotów jest dostępny na licencji <a href="https://creativecommons.org/licenses/by/4.0/deed.pl">CC BY 4.0</a></p>
<h2 id="spis-tre-ci">Spis treści</h2>
<ul>
<li><a href="#basics">Konsola</a></li>
<li><a href="#strings">Ciągi znaków</a></li>
<li><a href="#values">Wartości i zmienne</a></li>
<li><a href="#functions">Korzystanie z funkcji</a></li>
<li><a href="#standard-library">Wbudowane funkcje JS</a></li>
<li><a href="#third-party-javascript">Pobieranie nowych funkcji</a></li>
<li><a href="#writing-functions">Pisanie własnych funkcji</a></li>
<li><a href="#loops">Pętle</a></li>
<li><a href="#arrays">Tablice</a></li>
<li><a href="#objects">Obiekty</a></li>
<li><a href="#callbacks">Wywołania zwrotne</a></li>
<li><a href="#recommended-reading">Do przeczytania później</a></li>
</ul>
<h2 id="nie-b-j-si-">Nie bój się!</h2>
<p><span class="right"><img src="images/yarnify.png" alt="cat"></span></p>
<p>Zawsze wylądujesz na czterech łapach — nawet programując! W przeciwieństwie do <a href="images/dealwithit.gif">przesuwania łapą szklanki z wodą</a> nad laptopem, <em>nic</em> nie wydarzy się twojemu komputerowi w trakcie tego kursu, nawet jeżeli wpiszesz niepoprawną komendę, lub naciśniesz nieodpowiedni przycisk. Tak jak koty, programiści co chwilę popełniają błędy. Mylą rzeczy, zapominają cudzysłowiów, nawiasów i zapominają, jak działają podstawowe funkcje (tj. włóczka lub laser). Programiści starają się bardziej, aby program <em>kiedykolwiek</em> zadziałał, aniżeli miałby zadziałać za pierwszym razem. Najlepiej uczyć się na błędach!</p>
<p>Nie musisz się obawiać! Najgorszą rzeczą, jaka może się stać będzie konieczność odświeżenia strony, jeżeli zabłądzsz. Nie przejmuj się, to dzieje się bardzo rzadko.</p>
<h2 id="-a-id-basics-href-basics-a-podstawy"><a id="basics" href="#basics">#</a> Podstawy</h2>
<p>Na tej stronie działa JavaScript. Pobawmy się nim trochę. Dla uproszczenia zakładam, że korzystasz z Google Chrome (lub pochodnej, np. Brave Opera, Chromium, Vivaldi…), jeżeli nie, będzie nam łatwiej, jeżeli będziesz korzystać z Chrome.</p>
<p>Na początek, naciśnij prawym przyciskiem na stronie i wybierz <strong>Zbadaj element</strong>, następnie przejdź do karty <strong>Konsola</strong>. Powinieneś zobaczyć coś takiego:</p>
<p><video width="632" height="196" controls loop>
<source src="images/console.webm" type="video/webm">
Twoja przeglądarka nie obsługuje tagu video.
</video></p>
<p>Jest to konsola, zwana często „wierszem poleceń” lub „terminalem”. Pozwala na wprowadzenie polecenia, na które dostaniemy natychmiastową odpowiedź. Jest bardzo użytecznym narzędziem do nauki (nadal korzystam z konsoli prawie każdego dnia, kiedy programuję).</p>
<p>W konsoli możemy zrobić trochę fajnych rzeczy. Gdy zacznę pisać, konsola podpowiada mi, jakie polecenia istnieją! Zobacz, co się stanie, gdy wpiszesz ‘1 + 1’ i naciśniesz Enter.</p>
<p>Korzystanie z konsoli jest ważnym elementem nauki JavaScript. Jeżeli nie wiesz, jak coś działa lub jakiego polecenia chcesz użyć, przejdź do konsoli i wypróbuj to! Przykład:</p>
<h3 id="-a-id-strings-href-strings-a-ci-gi-znak-w"><a id="strings" href="#strings">#</a> Ciągi znaków</h3>
<p>Będąc kotem, chcesz zastąpić wszystkie wystąpienia słowa „psy” w Internecie frazą „te podłe kundle”. Na początek wprowadź w konsolę kilka zdań zawierających słowo „psy” przynajmniej raz. W JavaScript, zbiór liter, cyfr i innych znaków nazywany jest <strong>ciągiem znaków</strong> (z ang. <em>string</em>). Ciągi znaków muszą zaczynać się I kończyć znakiem cudzysłowiu. Dozwolony jest zarówno pojedynczy (<code>'</code>), jak i podwójny (<code>"</code>), ale pamiętaj, aby użyć tego samego znaku na początku i na końcu.</p>
<p><video width="632" height="196" controls loop>
<source src="images/console-strings.webm" type="video/webm">
Twoja przeglądarka nie obsługuje tagu video.
</video></p>
<p>Widzisz tę okropną wiadomość o błędzie? Nie martw się – nie zrobiłeś nic nielegalnego. SyntaxError ILLEGAL jest jedynie komunikatem oznaczającym błąd w programie. Pierwsze dwa zdania miały pasujące znaki cudzysłowiu, ale łącząc oba, napotkał mnie błąd.</p>
<p>Dobrze, aby naprawić te zdania (zastępując „psy” naszą poprawioną wersją), musimy zapisać oryginalne zdania, aby wywołać je później w trakcie magicznego zastępowania. Zauważyłeś, że ciąg znaków jest powtarzany, kiedy wprowadzisz go w konsolę? To dlatego, że nie kazaliśmy zapisać komputerowi tego zdania, więc powraca ono do nas (lub pojawia się komunikat o błędzie, jeżeli zrobiliśmy coś nie tak).</p>
<h3 id="-a-id-values-href-values-a-warto-ci-i-zmienne"><a id="values" href="#values">#</a> Wartości i zmienne</h3>
<p><strong>Wartości</strong> (z ang. <em>values</em>) są najprostszymi komponentami w JavaScript. <code>1</code> jest wartością, <code>true</code> jest wartością, <code>'hello'</code> jest wartością, <code>function() {}</code> jest wartością, a lista jest jeszcze dłuższa! Jest wiele różnych <strong>typów</strong> wartości w JavaScript, ale nie musisz ich jeszcze znać — poznasz je w trakcie dalszej nauki, w miarę potrzeb.</p>
<p>Do przechowywania wartości używamy <strong>zmiennych</strong> (po ang. <em>variable</em>). Zmienna może przechowywać różne typy wartości, które mogą być zmieniane wielokrotnie. To tak jak skrzynki pocztowe. Przechowujemy coś w zmiennej, np. zdanie i przekazujemy zmiennej adres, którego możemy użyć później. W rzeczywistości skrzynki pocztowe posiadają swój numer, ale w JavaScript może to być dowolny ciąg małych liter i cyfr, bez spacji.</p>
<p><video width="632" height="196" controls loop>
<source src="images/console-variables.webm" type="video/webm">
Twoja przeglądarka nie obsługuje tagu video.
</video></p>
<p><code>var</code> jest skrótem wyrazu “variable”, a <code>=</code> oznacza <em>przechowaj wartość po prawej stronie w zmiennej po lewej stronie znaku</em>. Dodatkowo, jak mogłeś zauważyć, ponieważ przechowujemy wartość w zmiennej, konsola nie zwraca wpisanego zdania, lecz <code>undefined</code> (nieokreślony) co w tym przypadku oznacza <em>brak wartości do zwrócenia</em>.</p>
<p>Jeżeli wprowadzisz nazwę wartości w konsolę, zostanie wyświetlona jej wartość. Przechowywane wartości zostaną utracone, jeżeli zmienisz stronę. Dla przykładu, jeżeli odświeżę stronę, moja zmienna <code>dogSentence</code> zostanie wyczyszczona i przestanie istnieć. Nie przejmuj się tym na razie — używając klawiszy strzałek możesz powtórzyć ostatnio wykonywane polecenia.</p>
<h3 id="-a-id-functions-href-functions-a-funkcje"><a id="functions" href="#functions">#</a> Funkcje</h3>
<p>Ponieważ przechowujemy już wartość w zmiennej, teraz zmieńmy jej wartość! Możemy użyć do tego <em>funkcji</em> (<em>function</em>). Funkcje to rodzaje wartości, spełniające określone zadanie (akcję).</p>
<p>JavaScript posiada funkcję o nazwie <code>replace</code>, która robi dokładnie to, czego oczekujemy! Funkcje przyjmują dowolną liczbę parametrów w nawiasach (zero, jedną lub więcej) i zwracają albo <code>undefined</code>, albo zmieniony ciąg znaków lub inną wartość. Funkcja <code>replace</code> może być używana na każdym ciągu znaków i wymaga podania dwóch wartości: ciąg znaków do usunięcia i ciąg znaków, który go zastąpi. Może to być ciężkie do zrozumienia, więc spójrz na przykład:</p>
<p><video width="632" height="196" controls loop>
<source src="images/console-replace.webm" type="video/webm">
Twoja przeglądarka nie obsługuje tagu video.
</video></p>
<p>Zauważyłeś, że <code>dogSentence</code> nie zmienia się po wykonaniu <code>replace</code>? To dlatego, że <code>replace</code>, (i większość podobnych funkcji) pobiera wartość i zwraca <strong>nową wartość</strong>, bez modyfikacji przekazanej. Ponieważ nie przekazaliśmy wyniki działania funkcji (brak <code>=</code> przed funkcją <code>replace</code>) wynik został jedynie przedstawiony w konsoli.</p>
<h3 id="-a-id-standard-library-href-standard-library-a-biblioteka-standardowa-"><a id="standard-library" href="#standard-library">#</a> „Biblioteka standardowa”</h3>
<p>Możesz zastanawiać się, ile (i jakie) funkcji znajduje się jeszcze w JavaScript. Odpowiedź: DUUUUŻO! Jest wiele <strong>wbudowanych, ustandaryzowanych bibliotek</strong>, o których możesz dowiedzieć się na MDN (strona Mozilli zawierająca dokładne informacje o technologiach webowych). Przykładowo, <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math">strona JS'owego obiektu Math</a>.</p>
<h3 id="-a-id-third-party-javascript-href-third-party-javascript-a-biblioteki-os-b-trzecich"><a id="third-party-javascript" href="#third-party-javascript">#</a> Biblioteki osób trzecich</h3>
<p>Jest wiele kodu JavaScript przeznaczonego do ponownego użytku, który <strong>nie jest wbudowany</strong>. Taki kod JavaScript osób trzecich zwykle jest nazywany „bibliotekami” (libraries) lub „wtyczkami” (plugins). Jedną z moich ulubionych jest <strong>Underscore.js</strong>. Zdobądźmy go i użyjmy na stronie! Na początek odwiedźmy <a href="http://underscorejs.org/">http://underscorejs.org/</a> i naciśnijmy odnośnik do pobrania (zwykle używam wersji rozwojowych, ponieważ są łatwiejsze w czytaniu i posiadają tą samą podstawową funkcjonalność). Następnie skopiuj kod biblioteki do schowka (możesz użyć opcji Zaznacz wszystko). Wklej go w konsolę i naciśnij enter. Przeglądarka ma teraz nową wartość: <code>_</code>. Underscore daje wiele przydatnych funkcji. Nauczysz się z nich korzystać później.</p>
<p><video width="632" height="196" controls loop>
<source src="images/underscore.webm" type="video/webm">
Twoja przeglądarka nie obsługuje tagu video.
</video></p>
<h3 id="-a-id-writing-functions-href-writing-functions-a-pisanie-w-asnych-funkcji"><a id="writing-functions" href="#writing-functions">#</a> Pisanie własnych funkcji</h3>
<p>Nie jesteś ograniczony do korzystania z funkcji napisanych przez innych — możesz też utworzyć własną. Zróbmy to! Utwórzmy prostą funkcję <code>makeMoreExciting</code> , która doda kilka wykrzykników na koniec zdania, czyniąc zdanie dużo bardziej ekscytującym.</p>
<pre><code>function makeMoreExciting(string) {
return string + '!!!!';
}
</code></pre><p>Można to odczytać jako: „istnieje funkcja 'make more exciting', która pobiera ciąg znaków i zwraca jego kopię z dodatkowymi wykrzyknikami na końcu”. Tak napisalibyśmy to w konsoli, gdybyśmy nie użyli funkcji</p>
<p><video width="632" height="196" controls loop>
<source src="images/custom-function-manually.webm" type="video/webm">
Twoja przeglądarka nie obsługuje tagu video.
</video></p>
<p>Wyrażenie <code>string + '!!!!'</code> zwraca nowy wiersz, a nasza zmienna o nazwie <code>string</code> nie zmienia swojego stanu.</p>
<p>Wykorzystajmy naszą funkcją, zamiast robić to manualnie. Po pierwsze, wklej funkcję w konsolę i <strong>wywołaj</strong> ją <strong>przekazując</strong> argument w postaci ciągu znaków:</p>
<p><video width="632" height="196" controls loop>
<source src="images/custom-function-call.webm" type="video/webm">
Twoja przeglądarka nie obsługuje tagu video.
</video></p>
<p>Możesz też wywołać tę samą funkcję przekazując zmienną wskazującą na ciąg znaków (w powyższym przykładzie po prostu wprowadziliśmy zmienną, zamiast zapisywać ją do zmiennej):</p>
<p><video width="632" height="196" controls loop>
<source src="images/custom-function-call-variable.webm" type="video/webm">
Twoja przeglądarka nie obsługuje tagu video.
</video></p>
<p>Wiersz <code>makeMoreExciting(sentence)</code> jest równoznaczny z poleceniem <code>sentence + '!!!!'</code>. Co, jeżeli chcemy <strong>zapisać</strong> (zaktualizować) wartość zdania? Zapiszmy zwracaną wartość do naszego zdania.</p>
<pre><code>var sentence = "time for a nap";
sentence = makeMoreExciting(sentence);
</code></pre><p>Od teraz <code>sentence</code> posiada znak równości! Pamiętaj, że używasz słowa kluczowego <code>var</code> tylko podczas <strong>inicjalizacji</strong> zmiennej — przy jej pierwszym użyciu. Nie powinieneś później używać <code>var</code> jeżeli nie zamierzasz ponownie inicjalizować (wyczyścić) tej wartości.</p>
<p>Co się stanie, jeżeli usuniemy instrukcję <code>return</code> z funkcji?</p>
<p><video width="632" height="196" controls loop>
<source src="images/custom-function-no-return.webm" type="video/webm">
Twoja przeglądarka nie obsługuje tagu video.
</video></p>
<p>Dlaczego zmienna <code>sentence</code> jest pusta? Funkcje domyślnie zwracają <code>undefined</code>! Możesz wybrać wartość zwracaną przez funkcję. Funkcje powinny pobierać wartość i zwracać ją. (ciekawostka: nazywają to mądrze <em>programowaniem funkcyjnym</em>). Następna funkcja, która nie zwraca żadnej wartości, ale używa innej metody, aby wyświetlić wynik:</p>
<pre><code class="lang-js">function yellIt(string) {
string = string.toUpperCase();
string = makeMoreExciting(string);
console.log(string);
}
</code></pre>
<p>Funkcja <code>yellIt</code> korzysta z naszej funkcji <code>makeMoreExciting</code> oraz wbudowanej metody <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toUpperCase">toUpperCase</a>. Metody to po prostu funkcje, które należą do czegoś — w tym przypadku do ciągu znaków (możemy nazywać ją zarówno metodą, jak i funkcją). <code>makeMoreExciting</code> nie należy do niczego, więc technicznie nie jest funkcją (może to być skomplikowane, wiem…).</p>
<p>Ostatni wiersz funkcji po prostu wyświetla podaną wartość w konsoli.</p>
<p><video width="632" height="196" controls loop>
<source src="images/custom-function-console-log.webm" type="video/webm">
Twoja przeglądarka nie obsługuje tagu video.
</video></p>
<p>Jest więc coś nie tak z powyższą funkcją? To zależy! Istnieją dwa główne rodzaje funkcji:</p>
<ul>
<li>funkcje, które modyfikują lub tworzą wartości i zwracają je</li>
<li>funkcje pobierające wartości i wykonujące na nich operacje, nie zwracając niczego</li>
</ul>
<p><code>console.log</code> jest przykładem drugiego rodzaji funkcji: wyświetla tekst w konsoli — możesz zobaczyć efekt działania funkcji, ale nie może zostać on reprezentowany w formie wartości JavaScript. Moją zasadą jest starać się, aby istniały oba rodzaje funkcji, niezależnie od siebie. Tak wygląda napisana na nowo funkcja <code>yellIt</code>:</p>
<pre><code class="lang-js">function yellIt(string) {
string = string.toUpperCase();
return makeMoreExciting(string);
}
console.log(yellIt("nie boję się ludzi"));
</code></pre>
<p>W ten sposób <code>yellIt</code> staje się bardziej <strong>ogólne</strong>, co oznacza że funkcja spełnia wyłącznie swoje zadanie, nie wyświetlając wyniku — ta możliwość może zostać dodana później, poza deklaracją funkcji.</p>
<h3 id="-a-id-loops-href-loops-a-p-tle"><a id="loops" href="#loops">#</a> Pętle</h3>
<p>Teraz, gdy mamy pod pasem podstawowe umiejętności (<em>Od autora: czy koty noszą pasy?</em>) możemy się trochę rozleniwić. Co?! Tak, to prawda: programowanie uczy lenistwa. Larry Wall, twórca języka programowania Perl, nazwał lenistwo <a href="http://c2.com/cgi/wiki?LazinessImpatienceHubris">najważniejszą cechą</a> dobrego programisty. Jeżeli komputery nie wykonywałyby naszych zadań, musielibyśmy robić to wszystko ręcznie, zamiast opalać się w słońcu, podczas gdy program działa dla ciebie. Czy to nie wspaniałe?</p>
<p>Pętle (<em>loops</em>) są jednym z najważniejszych sposobów na opanowanie możliwości komputera. Pamiętasz wspomniane wcześniej <code>Underscore.js</code>? Upewnij się, że załadowałeś je. (pamiętaj: możesz użyć strzałki w górę na klawiaturze i nacisnąć enter) i wklej ten kod w konsolę:</p>
<pre><code class="lang-js">function logANumber(someNumber) {
console.log(someNumber);
}
_.times(10, logANumber);
</code></pre>
<p>Ten kod używa metody Underscore o nazwie <a href="http://underscorejs.org/#times">times</a>, która pobiera jedną liczbę i funkcję, która wyświetla, ile razy wykorzystano funkcję.</p>
<p><img src="images/times-loop.png" alt="console"></p>
<p>Chcąc napisać to ręcznie, wyglądałoby to tak:</p>
<pre><code class="lang-js">logANumber(0);
logANumber(1);
logANumber(2);
logANumber(3);
logANumber(4);
logANumber(5);
logANumber(6);
logANumber(7);
logANumber(8);
logANumber(9);
</code></pre>
<p>Ale koty nigdy nie wykonują niepotrzebnej pracy, więc musisz pytać siebie, <em>„czy używam najbardziej leniwej metody, aby to wykonać?”</em>.</p>
<p>Dlaczego jest to nazywane zapętlaniem? Pomyśl to tak. Jeżeli chcielibyśmy wypisać 10 cyfr (od 0 do 9) używając tablicy w JavaScript, wyglądałoby to tak:</p>
<pre><code class="lang-js">var zeroThroughTen = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
</code></pre>
<p>Metoda <code>times</code> w rzeczywistości tworzy taką tablicę i dla każdej liczby wykonuje zadanie: w tym przypadku wywołuje funkcję <code>logANumber</code> z obecną liczbą.</p>
<h3 id="-a-id-arrays-href-arrays-a-tablice"><a id="arrays" href="#arrays">#</a> Tablice</h3>
<p>Wspomniałem o nich już kilka razy, ale poświęćmy minutę, aby się ich nauczyć. Wyobraź sobie, że musisz, śledzić wszystkich swoich kocich towarzyszy. Z tablic będzie to proste. Myśl o tablicach, jak o uporządkowanych listach, w których możesz przechowywać wiele elementów.</p>
<p>Jak utworzyć tablicę:</p>
<pre><code class="lang-js">var myCatFriends = ["bill", "tabby", "ceiling"];
</code></pre>
<p>Teraz masz listę swoich kocich przyjaciół!</p>
<p>Elementy tablicy są przypisywane od numeru 0 w górę. Więc <code>myCatFriends[0]</code> zwraca <code>bill</code>, a <code>myCatFriends[1]</code> — <code>tabby</code>… itd.</p>
<p>Aby uzyskać imiona przyjaciół z naszej nowej tablicy, możesz uzyskać dostęp bezpośrednio, np.:</p>
<pre><code class="lang-js">console.log(myCatFriends[0]);
</code></pre>
<p><img src="images/array-access.png" alt="console"></p>
<p>Jeżeli byłeś w najmodniejszym klubie kota i zdobyłeś nowego przyjaciela ostatniej nocy, aby łatwo go dodać do tablicy, wprowadź: <code>myCatFriends.push("super hip cat");</code>.</p>
<p>Aby sprawdzić, czy nowy kot został dodany do tablicy, użyj <code>.length</code>:</p>
<p><img src="images/array-push-length.png" alt="console"></p>
<p>Zauważyłeś, że <code>push</code> zwróciło długość? Wygodnie! Pamiętaj też, że i tablice zawsze <strong>zachowują kolejność</strong>, co oznacza, że pamiętają kolejność, w której dodano lub zdefiniowano elementy. Nie wszystko w JavaScript tak działa, więc zapamiętaj tę specyfikę tablic.</p>
<h3 id="-a-id-objects-href-objects-a-obiekty"><a id="objects" href="#objects">#</a> Obiekty</h3>
<p>Tablice są dobre dla list, ale może być ciężko używać ich do innych działań. Wyobraź sobie tablicę kocich przyjaciół. Co, jeżeli chciałbyś przechować więcej, niż tylko imiona?</p>
<pre><code class="lang-js">var myCatFriends = ["bill", "tabby", "ceiling"];
var lastNames = ["the cat", "cat", "cat"];
var addresses = ["The Alley", "Grandmas House", "Attic"];
</code></pre>
<p>Czasem dobrze jest trzymać wszystkie adresy i imiona w jednej wartości. Ale czasem masz „kota w mózgu”, więc chcesz przywołać Billa i sprawdzić jego adres. Z tablicami zajmuje to dużo pracy, ponieważ nie możesz powiedzieć „tablico, daj mi adres Bill” ponieważ Bill jest w jednej tablicy, a jego adres w zupełnie innej.</p>
<p><img src="images/array-lookup.png" alt="console"></p>
<p>Może to być nierozsądne, ponieważ jeżeli zmieni się zawartość tablicy i dodamy nowego kota na początek, powinniśmy zaktualizować też zmienną <code>billsPosition</code>, aby zawierała obecny adres Billa. Istnieje prostszy sposób na zarządzanie takimi danymi, wykorzystując obiekty:</p>
<pre><code class="lang-js">var firstCat = { name: "bill", lastName: "the cat", address: "The Alley" };
var secondCat = { name: "tabby", lastName: "cat", address: "Grandmas House" };
var thirdCat = { name: "ceiling", lastName: "cat", address: "Attic" };
</code></pre>
<p>Dlaczego robimy to w ten sposób? Ponieważ teraz mamy zmienną dla każdego kota, której możemy użyć do przechowywania danych w wygodniejszy i czytelniejszy sposób.</p>
<p><img src="images/object-lookup.png" alt="console"></p>
<p>Możesz myśleć o obiektach jak o kluczach na breloku. Każdy jest przeznaczony do konkretnych drzwi, i jeżeli są one podpisane, możesz używać ich bez problemu. W rzeczywistości, elementy po lewej od dwukropka nazywane są <strong>kluczami</strong> (lub <strong>właściwościami*"), a elementy po prawej to </strong>wartości** </p>
<pre><code class="lang-js">// obiekt z kluczem 'name' i jedną wartością 'bill'
{ name: 'bill' };
</code></pre>
<p>Dlaczego miałbyś więc używać tablic, kiedy możesz użyć obiektów? Niestety, obiekty nie zapamiętują kolejności wprowadzonych danych. Możesz zdefiniować obiekt tak:</p>
<pre><code class="lang-js">{ date: "10/20/2012", diary: "spałem dziś trochę", name: "Charles" };
</code></pre>
<p>Ale komputer może go wyświetlić tak:</p>
<pre><code class="lang-js">{ diary: "spałem dziś trochę", name: "Charles", date: "10/20/2012" };
</code></pre>
<p>Albo tak!</p>
<pre><code class="lang-js">{ name: "Charles", diary: "spałem dziś trochę", date: "10/20/2012" };
</code></pre>
<p>Nie powinieneś więc ufać kolejności kluczy w obiektach. Jeżeli chcesz zrobić to naprawdę dobrze, możesz utworzyć tablicę wypełnioną obiektami, lub obiekt zawierający tablice!</p>
<pre><code class="lang-js">var moodLog = [
{
date: "10/20/2012",
mood: "osadzony"
},
{
date: "10/21/2012",
mood: "zaskoczony"
},
{
date: "10/22/2012",
mood: "mruczący"
}
];
// segregowane od najmniej do najbardziej ulubionych
var favorites = {
treats: ["obserwacja ptaków", "pocieranie brzucha", "kocimiętka"],
napSpots: ["sofa", "skrzynka", "ludzka twarz"]
};
</code></pre>
<p>Kiedy łączysz różne rodzaje kontenerów, tworzysz <strong>struktury danych</strong>, jak z klocków lego!</p>
<h3 id="-a-id-callbacks-href-callbacks-a-wywo-ania-zwrotne"><a id="callbacks" href="#callbacks">#</a> Wywołania zwrotne</h3>
<p>Wywołania zwrotne nie są w rzeczywistości możliwością JavaScript, tak jak obiekty czy tablice, są natomiast jednym ze sposobów na używanie funkcji. Aby zrozumieć, dlaczego odwołania są przydatne, musisz najpierw rozumieć programowanie asynchroniczne (często skracane do <strong>async</strong>). Asynchroniczny kod z definicji jest kodem pisanym w niesynchroniczny sposób. Kod synchroniczny jest prosty do zrozumienia i napisania. Przykład:</p>
<pre><code class="lang-js">var photo = download('http://foo-chan.com/images/sp.jpg');
uploadPhotoTweet(photo, '@maxogden');
</code></pre>
<p>Ten synchroniczny <a href="http://pl.wikipedia.org/wiki/Pseudokod">pseudokod</a> pobiera zdjęcie słodkiego kotka, wysyła je na Twitterze i tweetuje do <code>@maxogden</code>. Proste i zrozumiałe!</p>
<p>(<em>Od autora: Ja, @maxogden z radością przyjmę każde zdjęcie kota na Twitterze</em>)</p>
<p>Ten kod jest synchroniczny, ponieważ aby zdjęcie zostało wysłane na Twittera, musi zostać pobrane. Oznacza to, że 2 wiersz nie może zostać wykonany przed zakończeniem 1. Jeżeli chcielibyśmy zaimplementować ten kod, musimy się upewnić, że pobieranie „zablokowało” wykonywanie dalszego kodu, dopóki się nie zakończy, a po zakończeniu, pozwoli na wykonanie dalszego kodu i wykona się drugi wiersz.</p>
<p>Synchroniczny kod jest dobry, kiedy rzeczy dzieją się szybko, ale jest okropny, gdy coś wymaga zapisania, ładowania, pobierania i wysyłania. Co, jeśli serwer z którego pobierasz zdjęcie jest powolny, twoje połączenie z internetem jest powolne, lub komputer z którego korzystasz ma uruchomione za dużo kart z kocimi filmikami, więc działa wolniej? Oznacza to, że będzie trzeba poczekać, zanim 2 linia kodu zostanie wykonana. W międzyczasie, ponieważ cały JavaScript ze strony nie może być wykonywany, strona zamrozi się i utraci responsywność, zanim ukończy się pobieranie.</p>
<p>Blokowanie wykonywania powinno być unikane za wszelką cenę, szczególnie gdy czyni program nieresponsywnym lub mrozi go. Załóżmy, że pobieranie zdjęcia zajmuje jedną sekundę. Aby zilustrować, ile znaczy sekunda dla współczesnego komputera, tutaj znajduje się program, który obliczy, ile zadań potrafi wykonać JavaScript w przeciągu sekundy.</p>
<pre><code class="lang-js">function measureLoopSpeed() {
var count = 0;
function addOne() { count = count + 1 };
// Date.now() zwraca ogromną liczbę wyrażoną w milisekundach,
// które minęły od 1 stycznia 1970;
var now = Date.now();
// Zapętl tak długo, jak Date.now() nie będzie o 1000 milisekund (1 sekunda) lub
// więcej od początku pętli. Za każdym razem użyj addOne()
while (Date.now() - now < 1000) addOne();
// Kiedy będzie to >= 1000ms, wypiszmy liczbę wykonanych zadań
console.log(count);
}
measureLoopSpeed();
</code></pre>
<p>Wklej ten kod do swojej konsoli JavaScript, a po sekundzie otrzymasz wypisaną liczbę. Na moim komputerze jest to <code>8527360</code>, czyli około <strong>8,5 miliona</strong>. W ciągu jednej sekundy JavaScript może wywołać funkcję <code>addOne</code> 8,5 miliona razy! Więc, pobierając zdjęcie kodem synchronicznym, potencjalnie zatrzymuje wykonywanie aż 8,5 miliona operacji!</p>
<p>Niektóre języki posiadają funkcję <code>sleep</code>, która blokuje wykonywanie kodu na kilka sekund. Dla przykładu, kod <a href="http://en.wikipedia.org/wiki/Bash_%28Unix_shell%29"><code>bash</code></a>a uruchomiony na dystrybucji GNU/Linuxa używający polecenia <code>sleep</code>. Po wykonaniu <code>sleep 3 && echo 'koniec snu'</code>, po 3 sekundach zostanie wyświetlony tekst <code>koniec snu</code>.</p>
<p><img src="images/bash-sleep.png" alt="console"></p>
<p>JavaScript nie posiada tej funkcji. Zapewne, jako kot zapytasz mnie: „Dlaczego uczę się języka, który nie uwzględnia snu?”. Posłuchaj. Zamiast polegać na <code>sleep</code>, JS zachęca do używania funkcji. Jeżeli chcesz poczekać na ukończenie zadania A, zanim wykonasz B, wstawiasz kod zadania B do funkcji, którą wywołasz, gdy A zostanie wykonane.</p>
<p>Przykład blokującego kodu:</p>
<pre><code class="lang-js">a();
b();
</code></pre>
<p>Przykład nieblokującego kodu:</p>
<pre><code class="lang-js">a(b);
</code></pre>
<p>W nieblokującej wersji, <code>b</code> wywołuje <code>a</code>. W blokującej wersji, zarówno <code>a</code> jak i <code>b</code> są wywoływane (obie mają <code>()</code> po sobie). W nieblokującej wersji, zauważysz że tylko In the non-blocking version you will notice that only <code>a</code> zostanie wywołane, a <code>b</code> zostanie przekazane jako argument.</p>
<p>W blokującej wersji, nie ma bezpośredniej relacji pomiędzy <code>a</code> i <code>b</code>. W nieblokującej wersji, do <code>a</code> należy to, co ma robić, po czym wywoła <code>b</code>. Jest to nazywane wywołaniach zwrotnymi, ponieważ nasza funkcja zwrotna, w tym przypadku <code>b</code>, zostanie wywołana po wykonaniu <code>a</code>.</p>
<p>Implementacja w pseudokodzie, jak może wyglądać funkcja <code>a</code>:</p>
<pre><code class="lang-js">function a(done) {
download('https://pbs.twimg.com/media/B4DDWBrCEAA8u4O.jpg:large', function doneDownloading(error, png) {
// obsługa błędów, jeżeli takie się wydarzą
if (error) console.log('kruci hegot, niedoróba!', error);
// wywołaj, jeśli wszystko się wykonało
done();
})
}
</code></pre>
<p>Wróćmy do nieblokującego przykładu, <code>a(b)</code>, gdzie wywołaliśmy <code>a</code> i przekazaliśmy <code>b</code> jako pierwszy argument. W deklaracji funkcji <code>a</code>, <code>done</code> jest przekazaną przez nas funkcją <code>b</code>. Na początku trudno to ułożyć sobie w głowie. Kiedy wywołasz funkcję, przekazane argumenty nie nazywają się tak, jak przy wywołaniu funkcji. W tym wypadku <code>b</code> jest nazwane <code>done</code> wewnątrz funkcji. <code>b</code> i <code>done</code> są jednak nazwami zmiennych odnoszących się do tej samej funkcji. Zwykle *funkcje callback" są nazywane <code>done</code> lub <code>callback</code>, aby było jasne, że mają być one wykonane po wykonaniu zadania funkcji.</p>
<p>Więc tak długo, jak <code>a</code> wykonuje swoją pracę i <code>b</code> kiedy jest gotowe, <code>a</code> i <code>b</code> są wywoływane w zarówno blokującej j nieblokującej wersji. Różnicą jest to, że w nieblokującej wersji nie musisz wstrzymywać wykonywania kodu. Zwykle nieblokujący kod to ten, w którym funkcja zwraca wynik tak szybko, jak to możliwe, bez blokowania czegokolwiek.</p>
<p>Aby dostatecznie to wytłumaczyć: Jeżeli <code>a</code> wykonuje się jedną sekundę i używasz blokującej wersji, możesz robić tylko jedną rzecz. Jeżeli używasz wywołań zwrotnych (wersji nieblokującej), możesz wykonywać <em>dosłownie miliony</em> innych działań w tej samej sekundzie, więc możesz wykonać swoją pracę miliony razy szybciej i spać przez resztę dnia.</p>
<p>Pamiętaj: w programowaniu to ty masz być leniwy, ty masz spać, nie twój komputer.</p>
<p>Mam nadzieję, że zobaczysz, że wyrażenia zwrotne są po prostu funkcjami, które wywołują inne funkcje po pewnym asynchronicznym zadaniu. Typowe przykłady asynchronicznych zadań to odczytywanie zdjęć, pobieranie muzyki, wysyłanie zdjęć, korzystanie z bazy danych, oczekiwanie na sygnał od użytkownika itp. Wszystko, co zajmuje czas. JavaScript jest świetny w obsłudze asynchronicznych zadań, jeżeli tylko spędzisz czas na nauce używania wyrażeń zwrotnych i nie pozwolisz na blokowanie kodu.</p>
<h2 id="koniec-">Koniec!</h2>
<p>W zasadzie to dopiero początek twojej przygody z JavaScript! Nie nauczysz się wszystkiego naraz, ale możesz teraz spróbować nauczyć się wszystkiego, o czym wspomniałem.</p>
<p>Polecam wrócić tu jutro i przejrzeć ten kurs od początku! Może będziesz musiał próbować kilka razy, zanim wszystko zrozumiesz (programowanie jest czasem trudne). Spróbuj też nie czytać tej strony w pokojach zawierających błyszczące przedmioty. To może rozpraszać…</p>
<p>Chcesz, aby poruszono tu inny temat? Zgłoś na <a href="http://github.com/maxogden/javascript-for-cats">stronie oryginalnego projektu</a> lub <a href="http://github.com/mkljczk/jscatspl">stronie polskiego tłumaczenia</a> w serwisie GitHub.</p>
<h3 id="-a-id-recommended-reading-href-recommended-reading-a-do-przeczytania"><a id="recommended-reading" href="#recommended-reading">#</a> Do przeczytania</h3>
<p> JavaScript dla kotów pomija wiele szczegółów, które nie są ważne na początek (koty nie są tym aż tak zainteresowane), ale jeśli chcesz zagłębić się w to, sprawdź te pozycje:</p>
<ul>
<li><a href="http://nodeschool.io/">NodeSchool.io</a> jest rozwijanym przez społeczność, otwartoźródłowym oprogramowaniem edukacyjnym, które uczy różnych umiejętności wymaganych przy tworzeniu stron internetowych. Pomagałem przy tworzeniu NodeSchool! Szkoda, że nie ma tam aż tylu kotów…</li>
<li><a href="http://eloquentjavascript.net/">Eloquent Javascript</a> jest bezpłatną książką do nauki JavaScript. Jest bardzo dobra! Szczególnie rozdział o <a href="http://eloquentjavascript.net/chapter2.html">wartościach, zmiennych i przepływach danych</a></li>
<li><a href="https://developer.mozilla.org/pl/docs/JavaScript/Guide">Podręcznik JavaScript Mozilli</a> (w języku polskim!) również ma fajne wprowadzenie do <a href="https://developer.mozilla.org/pl/docs/Web/JavaScript/Guide/Składnia_i_typy">składni języka i typów</a></li>
<li><a href="https://github.com/feross/standard">Przewodnik stylu JS <code>standard</code></a> jest podręcznikiem do stylu JavaScript, którego używam</li>
<li><a href="https://github.com/shama/letswritecode">Let's Write Code by @shama</a> jest serią poradników w serwisie YouTube na kanale mojego przyjaciela</li>
</ul>
<p><hr></p>
<h3 id="-a-id-satisfied-customers-href-satisfied-customers-a-zadowoleni-czytelnicy"><a id="satisfied-customers" href="#satisfied-customers">#</a> Zadowoleni czytelnicy</h3>
<center><img src="images/customers5.jpg" alt="satisfied customer"></center>
<center><img src="images/customers1.png" alt="satisfied customer"></center>
<center><img src="images/customers2.png" alt="satisfied customer"></center>
<center><img src="images/customers3.png" alt="satisfied customer"></center>
<center><img src="images/customers4.png" alt="satisfied customer"></center>
<p><em>JSForCats.com jest darem miłości od <a href="http://twitter.com/maxogden">@maxogden</a>. Jeżeli chcesz uczynić poradnik lepszym, zapraszam <a href="http://github.com/maxogden/javascript-for-cats">tutaj</a> (oryginalna, angielska wersja na licencji CC-0) lub <a href="http://github.com/mkljczk/jsforcats">tutaj</a> (polskie tłumaczenie)</em></p>
<center><img src="images/awesome.jpg" alt="console"></center>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-34180924-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>