Wartości w JavaScript

Cześć! To jest fragment książki JavaScript od zupełnych podstaw, która ma pomóc w nauce programowania od zera. Zaangażuj się zostawiając komentarze (najedź myszką na tekst, by zobaczyć po prawej dymek komentowania), albo zostań recenzentem.

W poprzednim rozdziale nauczyliśmy się jak napisać kod JavaScript, drukujący tekst w konsoli:

console.log("Witaj, świecie"); // Witaj, Świecie

Kiedy na niego spoglądasz, być może zastanawiasz się, dlaczego wygląda on tak, a nie inaczej. Czym jest console? Czym jest log? I wreszcie — czemu tekst Witaj, świecie opakowany jest w cudzysłowy? Wszystko się z czasem wyjaśni. console poznamy przy okazji obiektów, log przy okazji funkcji. Teraz zaś pomówmy o wartości "Witaj, świecie".

Teksty, znane jako stringi

Cudzysłowy służą do określenia wartości tekstowej. Gdy czytasz książkę, cudzysłowy często określają co dokładnie powiedział lub pomyślał bohater. Podobnie w programowaniu, otaczają dokładną wartość tekstową.

// Język pisany
Wypisz "Witaj, świecie"

// JavaScript
console.log("Witaj, świecie"); // Witaj, Świecie

Tekst w cudzysłowach nie zostanie zinterpretowany, czyli nawet gdyby zawierał instrukcję, nie zostanie ona wykonana. Jest wartością zawierającą tekst litera po literze. Z taką wartością możemy coś zrobić, na przykład przekazać ją do console.log. Choć raczej nie ma to sensu — równie dobrze moglibyśmy też nic z nią nie zrobić.

console.log(10); // 10

// Powstanie wartość i nic się z nią nie stanie
"console.log(10);"

console.log("console.log(10);"); // console.log(10);

Stringi?

Wartości tekstowe w programowaniu są zwykle nazywane stringami. Wzięło się to od angielskiego słówka: string, oznaczającego sznur lub strunę, ze względu na to, że przypominają sznur znaków. Mogą mieć rozmaite długości, można je łączyć albo przycinać, można nawet ze środka wyciąć mały kawałek. Ta nazwa utarła się i stała się standardem w niemal wszystkich językach do dziś. Po angielsku w programowaniu przyjęło się mówić "string" na wartości tekstowe. Czasem stosuje się spolszczenie "ciąg znaków" albo "łańcuchy znaków", ale rzadko kiedy ktoś tak mówi. Programiści mówią "stringi"1, a że celem tej książki jest uczenie wiedzy praktycznej, więc i ja nie będę się wyłamywał od takiego nazewnictwa.

Cudzysłowy

W JavaScript stringi można tworzyć przy użyciu cudzysłowu podwójnego ", pojedynczego ', lub znaku grawisa ` (w programowaniu nazywany backtick lub backquote).

Istnieją pewne różnice między tymi opcjami, ale na ten moment nie musimy o nich wiedzieć. W większości przypadków efekt ich działania będzie identyczny. W książce zdecydowałem się na użycie podwójnego cudzysłowu ", który uważam za najprostszy dla początkujących.

console.log("Witaj, świecie"); // Witaj, Świecie
console.log('Witaj, świecie'); // Witaj, Świecie
console.log(`Witaj, świecie`); // Witaj, Świecie

Wiedza o różnych cudzysłowach może się przydać, gdy potrzebujesz uzyskać tekst z cudzysłowem. Jeśli potrzebujesz wyświetlić w tekście pojedynczy cudzysłów, otocz tekst podwójnymi. Jeśli podwójny, otocz pojedynczymi. Jeśli obydwa, otocz znakami grawisa.

console.log("Let's play"); // Let's play
console.log('Powiedział "Hej"'); // Powiedział "Hej"
console.log(`"Let's play"`); // "Let's play"

Dodawanie tekstów

W języku pisanym możemy łączyć ze sobą cytaty. Przykładowo, moglibyśmy powiedzieć:

// Język pisany
Wypisz "Witaj, " oraz "Świecie"

W programowaniu, wartości "Witaj, " oraz "Świecie" możemy połączyć w jedną przy użyciu znaku dodawania +, który postawiony pomiędzy dwoma stringami tworzy ich połączenie:

console.log("Witaj, " + "Świecie"); // Witaj, Świecie

Ćwiczenie: Stringi

Co zostanie wypisane w poniższym kodzie?

console.log('Kim jest "ona"?');
console.log("Użyję "+" by dodać teksty");
console.log("Tekst," + "następny," + "jeszcze jeden");

Odpowiedzi na końcu książki.

Liczby

Liczba również jest wartością. W JavaScript operujemy na liczbach rzeczywistych, czyli takich, które:

  • mogą być ujemne (z minusem na początku),
  • mogą mieć część dziesiętną (zapisywaną według zasad języka angielskiego, czyli po kropce, np. 3.14 zamiast 3,14).
console.log(1); // 1
console.log(42); // 42
console.log(1.4); // 1.4
console.log(-10); // -10

Na liczbach możemy wykonywać operacje matematyczne. JavaScript wspiera wiele operacji, które część czytelników może pamiętać jeszcze ze szkoły:

  • Dodawanie +
  • Odejmowanie -
  • Mnożenie *
  • Dzielenie /
  • Reszta z dzielenia %
  • Podnoszenie do potęgi **
// Dodawanie
console.log(3 + 2); // 5
console.log(10 + 8); // 18
console.log(2 + 4); // 6

// Odejmowanie
console.log(3 - 2); // 1
console.log(10 - 8); // 2
console.log(2 - 4); // -2

// Mnożenie
console.log(3 * 2); // 6
console.log(10 * 8); // 80
console.log(2 * 4); // 8

// Dzielenie
console.log(3 / 2); // 1.5
console.log(10 / 8); // 1.25
console.log(2 / 4); // 0.5

// Reszta z dzielenia
console.log(3 % 2); // 1
console.log(10 % 8); // 2
console.log(2 % 4); // 2

// Podnoszenie do potęgi
console.log(3 ** 2); // 9
console.log(10 ** 8); // 100000000
console.log(2 ** 4); // 16

JavaScript można więc wykorzystywać jako kalkulator, nawet do obliczania wyników złożonych operacji. Domyślnie zachowana jest matematyczna kolejność działań, jak i również można stosować nawiasy:

console.log(1 + 2 * 3); // 7 (mnożenie przed dodawaniem)

console.log(1 + (2 * 3)); // 7
console.log((1 + 2) * 3); // 9

console.log(1 ** 2 + 2 ** 2 + 3 ** 2 + 4 ** 2); // 30
console.log(1 * 2 * 3 * 4 * 5); // 120
console.log(1 * 2 + 3 * 4 + 5 * 6); // 44

Tutaj warto sięgnąć pamięcią do poprzedniego rozdziału, gdzie uczyliśmy się jak używać konsoli. Jako że mamy ją zawsze pod ręką, możemy ją użyć zamiast kalkulatora.

Ćwiczenie: JavaScript jako kalkulator

Użyj JavaScript, aby ustalić, ile to jest:

  • 1 * 2 + 3 * 4 + 5 * 6 + 7 * 8 + 9
  • 1 * (2 + 3) * (4 + 5) * (6 + 7) * (8 + 9) (czy wartość ta będzie się różniła od powyższej?)
  • 1 * 2 / 3 * 4 / 5 * 6 / 7 * 8 / 9 * 10 (czy wartość ta będzie większa niż 1?)
  • 2102^{10} (czy spodziewasz się, że wartość ta będzie większa czy mniejsza niż 1000?)

Odpowiedzi na końcu książki.

Wartości logiczne: prawda i fałsz

Kolejnym istotnym typem wartości są wartości logiczne, czyli prawda true oraz fałsz false.

console.log(true); // true
console.log(false); // false

Są one przydatne w wielu przypadkach. Dla przykładu, mogą określać czy użytkownik wyraził zgodę na zbieranie danych (true) czy nie (false). W rozdziale o warunkach przekonamy się, że mogą one decydować, czy jakiś fragment kodu powinien zostać wywołany, czy nie. W przypadku pętli - ile razy będzie wykonywany. Wartości logiczne są bardzo przydane i istotne, tylko skąd się biorą?

Operator równości i nierówności

Wartości logiczne najczęściej powstają w wyniku porównywania dwóch wartości. Używamy do tego znaku potrójnej równości ===, który zwraca true gdy wartości są sobie równe, oraz false gdy nie są. Zadziała on dla znanych już nam liczb i stringów.

console.log(1 === 1); // true
console.log(1 === 2); // false

console.log("Marcin" === "Marcin"); // true
console.log("Marcin" === "Maciek"); // false

W innych źródłach możesz czasem spotkać się z podwójnym znakiem równości ==. Ma on znaczenie podobne do ===, ale w niektórych przypadkach jego zachowanie jest problematyczne. Dlatego powszechnie uważa się go za złą praktykę. To jak działa znak == w JavaScript jest znacznie bardziej skomplikowane, więc radzę ominąć ten temat. Jeśli się z nim spotkasz, najlepiej dokonaj zamiany na potrójny znak równości ===.

Funkcjonuje także operator !== sprawdzający, czy wartości są różne. W praktyce zwracana przez niego wartość logiczna jest zawsze odwrotna do tej zwracanej przez ===.

console.log(1 !== 1); // false
console.log(1 !== 2); // true

console.log("Marcin" !== "Marcin"); // false
console.log("Marcin" !== "Maciek"); // true

Te operatory można łączyć z innymi poznanymi operacjami:

console.log("Witaj, " + "Świecie" === "Witaj, Świecie");
// true
console.log(1 + 2 === 3); // true
console.log(1 + 2 !== 3); // false

Warto zauważyć, że powyższy kod wykonuje się poprawnie dzięki kolejności działań. Porównywanie === i !== wykonuje po operatorach arytmetycznych. By obliczyć 3 === 1 + 2, w pierwszej kolejności wykonywana jest operacja dodawania 1 + 2, a dopiero potem porównanie 3 === 3, zwracające wynik true.

Warto wiedzieć, że znak równości w programowaniu ma znaczenie nieco inne, niż znak równości w szkolnej matematyce. Gdy na matematyce widzieliśmy x * 2 = 4 to zakładaliśmy, że to równanie musi być spełnione, więc x musi być równy 2. W programowaniu sprawdzamy czy jest spełnione, czy nie. x może być na przykład równy 3 i wtedy równanie x * 2 === 4 zwróci false.

Operatory porównania dla liczb

Czasem może wystąpić potrzeba sprawdzenia, czy jedna wartość jest większa od drugiej. Do tego wykorzystujemy operatory porównania2:

  • > sprawdzający, czy to co jest po lewej stronie jest większe od tego, co jest po prawej,
  • < sprawdzający, czy to co jest po lewej stronie jest mniejsze od tego, co jest po prawej,
  • >= sprawdzający, czy to co jest po lewej stronie jest większe lub równe od tego, co jest po prawej,
  • <= sprawdzający, czy to co jest po lewej stronie jest mniejsze lub równe od tego, co jest po prawej.
console.log(1 > 3); // false
console.log(1 < 3); // true

console.log(2 > 3); // false
console.log(3 > 3); // false
console.log(4 > 3); // true

console.log(2 < 3); // true
console.log(3 < 3); // false
console.log(4 < 3); // false

console.log(2 >= 3); // false
console.log(3 >= 3); // true
console.log(4 >= 3); // true

console.log(2 <= 3); // true
console.log(3 <= 3); // true
console.log(4 <= 3); // false

Ćwiczenie: JavaScript jako kalkulator porównujący

Użyj JavaScript by sprawdzić, co jest większe:

  • 1 * 2 + 3 * 4 + 5 czy 1 + 2 * 3 + 4 * 5?
  • 2202^{20} czy 3153^{15}?
  • 2152^{15} czy 10410^4?

Odpowiedzi na końcu książki.

Typy wartości

Wszystkie liczby są ze sobą w pewien sposób powiązane. Wywodzą się jakby z jednego świata, mówiąc językiem matematyki "z jednej przestrzeni", a mówiąc językiem programowania "są tego samego typu". W przeciwieństwie do stringów czy wartości logicznych, które mają inne typy.

W programowaniu każda wartość ma swój typ. Typ określa właśnie to, z jakiej przestrzeni są dane wartości. Wszystkie liczby w JavaScript są typu number4. Wszystkie teksty (stringi) są typu string. Wszystkie wartości logiczne (czyli true i false) są typu boolean3. Typ określonej wartości można sprawdzić przy użyciu słówka typeof.

console.log(typeof 10); // number
console.log(typeof 0); // number
console.log(typeof -10); // number
console.log(typeof 0.1); // number

console.log(typeof ""); // string
console.log(typeof "Some text"); // string
console.log(typeof ("Text " + "another")); // string

console.log(typeof true); // boolean
console.log(typeof false); // boolean
console.log(typeof (1 > 2)); // boolean

Poza typami number, string i boolean, JavaScript wspiera jeszcze:

  • null5 oraz undefined, które wprowadzimy przy okazji omawiania zmiennych w rozdziale Zmienne,
  • funkcje6 (function), którym poświęcony jest rozdział Funkcje,
  • obiekty (object), którym poświęcony jest rozdział Obiekty.

Poza nimi warto wspomnieć również tablice, które są obiektami, ale mają specjalne wsparcie ze strony JavaScript. Opiszemy je w rozdziale Tablice.

Spokojnie, wszystko po kolei. W następnych rozdziałach poznamy te typy wartości i przekonamy się, jak wykorzystuje się je w programowaniu. Poznając kolejne bloki będziemy potrafili coraz więcej z nimi zrobić, a na koniec wykorzystamy je, by napisać własną grę. Gotowi? To ruszamy! Czas poznać zmienne.

1:

Językoznawcy często nie są zadowoleni z tego stanu rzeczy, ale zauważyłem, że programiści cechują się wyjątkową obojętnością wobec tego, z czego zadowoleni są językoznawcy, a z czego nie.

2:

Formalnie pojęcie operatora porównania obejmuje także === i !==. Nie znalazłem jednak słowa, które określałoby wyłącznie <, >, <= i >=. Uniknąłem też pojęcia operatora nierówności, gdyż w programowaniu silnie kojarzy się z !==.

3:

Nazwa tego typu pochodzi od nazwiska matematyka George Boole, który wprowadził metody algebraiczne do logiki tworząc tzw. algebrę Boole’a, traktującą true i false jako wartości oraz definiującą różne operacje takie jak i, lub czy nie.

4:

Formalnie jest jeszcze bigint do określania bardzo dużych liczb, ale jest bardzo rzadko wykorzystywany i nie będziemy o nim mówić.

5:

null w zasadzie jest typu "object", ale często jest zestawiany z undefined, który ma osobny typ.

6:

Funkcje formalnie są obiektami, choć z typeof zwracają "function".