Wartości w JavaScript

Cześć! To jest fragment książki JavaScript od podstaw, która ma pomóc w nauce programowania od zera.

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

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

Kiedy na niego patrzysz, 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 jest w cudzysłowie? 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 powiedział lub ewentualnie pomyślał bohater. Podobnie jest 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 robić.

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łowa "string", oznaczającego sznur lub strunę. Trochę przypominają sznur znaków: mogą mieć rozmaite długości, można je łączyć albo przycinać, można nawet wyciąć ze środka mały kawałek. Ta nazwa już się utarła i stała standardem w niemal wszystkich językach programowania używanych do dzisiaj. Programiści zaczęli używać tego pojęcia także w języku mówionym. 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 najłatwiejszy 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 chcesz 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. Moglibyśmy na przykład 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 utworzy 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(42); // 42
console.log(-1); // -1
console.log(2.71); // 2.71
console.log(-3.14); // -3.14

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ń oraz 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. Na przykład 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 przydatne 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 często uważa się go za złą praktykę. To jak działa znak == w JavaScript jest znacznie bardziej skomplikowane, więc polecam 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 === (czyli jeśli === zwróciłby true, to !== zwróci false, a jeśli === zwróciłby false, to !== zwróci true).

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 ===!== 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 truefalse) 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, stringboolean, 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,
  • symbol i bigint, które wykraczają poza zakres tej książki.

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 wymienione typy wartości i przekonamy się, jak wykorzystuje się je w programowaniu. Poznając kolejne bloki będziemy umieć 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 zadowolenia językoznawców.

2:

Formalnie pojęcie operatora porównania obejmuje także ===!==. Nie znalazłem jednak słowa, które określałoby wyłącznie <, >, <=>=. 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ą truefalse jako wartości oraz definiującą różne operacje, takie jak i, lub czy nie.

4:

Formalnie istnieje 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".