Kurs JavaScript i TypeScript · Moduł 1: Podstawy JavaScript
Konwersja typów i operacje na typach
W tej lekcji8
W Parku Jurajskim naukowcy często muszą przekształcać dane z jednej formy w drugą - tłumaczyć sekwencje DNA na atrybuty dinozaurów, konwertować pomiary między różnymi systemami czy analizować zachowania zwierząt. Podobnie w JavaScript, konwersja typów i operacje na typach danych to podstawowe umiejętności, które pozwalają na efektywne manipulowanie danymi.
Niejawna konwersja typów (Type Coercion)
JavaScript jest językiem dynamicznie typowanym (typ ma wartość, a nie zmienna) i słabo typowanym: gdy operacja tego wymaga, sam konwertuje wartości na inny typ. To jak automatyczne systemy adaptacyjne w Parku Jurajskim, które dostosowują się do zmian warunków - czasami wygodne, ale czasami zaskakujące.
Konwersja w operacjach arytmetycznych
Kiedy JavaScript wykonuje operacje arytmetyczne, próbuje automatycznie konwertować wartości na liczby:
1// String + Number -> String (konkatenacja)
2"Velociraptor " + 3; // "Velociraptor 3"
3
4// String - Number -> Number
5"50" - 10; // 40 (string "50" zostaje skonwertowany na liczbę)
6
7// String * Number -> Number
8"5" * 4; // 20 (string "5" zostaje skonwertowany na liczbę)
9
10// String / Number -> Number
11"20" / 5; // 4 (string "20" zostaje skonwertowany na liczbę)Zauważ szczególny przypadek operatora +, który dla stringów działa jako operator konkatenacji (łączenia), a nie dodawania. To jak obserwacja, że velociraptory zawsze polują w stadach - wiedza, która może uratować życie!
Konwersja w operacjach porównania
Kiedy porównujemy wartości różnych typów za pomocą operatora == (równość nieścisła), JavaScript próbuje je skonwertować na wspólny typ:
1// Number == String
25 == "5"; // true (string "5" zostaje skonwertowany na liczbę 5)
3
4// Boolean == Number
5true == 1; // true (true zostaje skonwertowany na 1)
6false == 0; // true (false zostaje skonwertowany na 0)
7
8// null == undefined
9null == undefined; // true (specjalny przypadek w specyfikacji)
10
11// Object == Primitive
12[1] == 1; // true ([1] zostaje skonwertowany na "1", a potem na 1)Takie zachowanie przypomina "intuicyjne" obserwacje w parku - "Ta zagroda wygląda tak samo jak tamta" - które mogą być mylące, jeśli nie znasz szczegółów.
Konwersja w operacjach logicznych
Operatory logiczne &&, || i ! mogą pracować z wartościami każdego typu, konwertując je niejawnie na boolean:
1// Operator ! (negacja) konwertuje wartość na boolean i neguje ją
2!0; // true (0 zostaje skonwertowane na false, a potem znegowane)
3!"Dino"; // false ("Dino" zostaje skonwertowane na true, a potem znegowane)
4
5// Operatory && i || mogą zwracać oryginalne wartości, a nie tylko boolean
6"T-Rex" && "Raptor"; // "Raptor" (jeśli pierwszy operand jest truthy, zwraca drugi)
70 || "Backup"; // "Backup" (jeśli pierwszy operand jest falsy, zwraca drugi)Ta logika jest jak protokół postępowania w parku: "Jeśli ogrodzenie działa ORAZ jest wysokie, dinozaur nie ucieknie" - obydwa warunki muszą być spełnione, aby całe zdanie było prawdziwe.
Jawna konwersja typów (Explicit Type Conversion)
Aby uniknąć nieoczekiwanych wyników niejawnej konwersji, często warto jawnie skonwertować wartości na pożądany typ. To jak precyzyjne protokoły laboratoryjne w Parku Jurajskim - dokładnie określone procedury dające przewidywalne rezultaty.
Konwersja na String
1// Metoda #1: Funkcja String()
2String(42); // "42"
3String(true); // "true"
4String(null); // "null"
5String(undefined); // "undefined"
6String({ name: "T-Rex" }); // "[object Object]"
7String([1, 2, 3]); // "1,2,3"
8
9// Metoda #2: Metoda toString()
10(42).toString(); // "42"
11true.toString(); // "true"
12[1, 2, 3].toString(); // "1,2,3"
13// null.toString(); // Błąd! Null i undefined nie mają metody toString()
14
15// Metoda #3: Konkatenacja z pustym stringiem
1642 + ""; // "42"
17true + ""; // "true"
18null + ""; // "null"Konwersja na Number
1// Metoda #1: Funkcja Number()
2Number("42"); // 42
3Number("42px"); // NaN (nie można skonwertować całego stringa na liczbę)
4Number(true); // 1
5Number(false); // 0
6Number(null); // 0
7Number(undefined); // NaN
8Number([1]); // 1 (jednoelementowa tablica jest konwertowana na jej element)
9Number([1, 2]); // NaN (tablica z wieloma elementami nie może być konwertowana)
10
11// Metoda #2: Funkcje parseInt() i parseFloat()
12parseInt("42"); // 42
13parseInt("42px"); // 42 (konwertuje, dopóki nie napotka nieprawidłowego znaku)
14parseInt("3.14"); // 3 (konwertuje tylko część całkowitą)
15parseFloat("3.14"); // 3.14 (konwertuje część zmiennoprzecinkową)
16
17// Metoda #3: Operatory unarny + i -
18+"42"; // 42
19-"42"; // -42
20+true; // 1Konwersja na Boolean
1// Metoda #1: Funkcja Boolean()
2Boolean(42); // true
3Boolean(0); // false
4Boolean(""); // false
5Boolean("text"); // true
6Boolean(null); // false
7Boolean(undefined); // false
8Boolean({}); // true (każdy obiekt jest truthy)
9
10// Metoda #2: Podwójna negacja !!
11!!42; // true
12!!0; // false
13!!"text"; // true
14!!null; // falseTabele konwersji
Poniższe tabele są jak tablice genetyczne dinozaurów w parku - pokazują, co dokładnie dzieje się podczas konwersji między różnymi typami.
Konwersja na String
| Typ wejściowy | Przykład wejściowy | Wynik konwersji na String |
|---|---|---|
| Number | 42 | "42" |
| Boolean | true | "true" |
| null | null | "null" |
| undefined | undefined | "undefined" |
| Array | [1, 2, 3] | "1,2,3" |
| Object | {name: "Rex"} | "[object Object]" |
| Function | function(){} | "function(){}" |
Konwersja na Number
| Typ wejściowy | Przykład wejściowy | Wynik konwersji na Number |
|---|---|---|
| String | "42" | 42 |
| String | " 42 " | 42 (białe znaki są usuwane) |
| String | "42px" | NaN |
| String | "" | 0 (pusty string) |
| Boolean | true | 1 |
| Boolean | false | 0 |
| null | null | 0 |
| undefined | undefined | NaN |
| Array | [] | 0 (pusta tablica) |
| Array | [5] | 5 (tablica z jednym elementem) |
| Array | [1, 2] | NaN (wiele elementów) |
| Object | {} | NaN |
Konwersja na Boolean
| Typ wejściowy | Przykład wejściowy | Wynik konwersji na Boolean |
|---|---|---|
| Number | 42 | true |
| Number | 0 | false |
| Number | NaN | false |
| String | "tekst" | true |
| String | "" | false |
| null | null | false |
| undefined | undefined | false |
| Object | {} (jakikolwiek) | true |
| Array | [] (jakakolwiek) | true |
Operacje na typach danych
Teraz zajmijmy się szczegółowymi operacjami na poszczególnych typach danych. To jak specjalistyczne procedury dla różnych gatunków dinozaurów.
Operacje na Stringach
Stringi w JavaScript oferują bogaty zestaw metod do manipulacji tekstem:
1const parkName = "Jurassic Park";
2
3// Długość stringa
4parkName.length; // 13
5
6// Dostęp do poszczególnych znaków
7parkName[0]; // "J"
8parkName.charAt(0); // "J" (alternatywna metoda)
9
10// Wyszukiwanie podciągów
11parkName.indexOf("Park"); // 9 (indeks, gdzie zaczyna się "Park")
12parkName.startsWith("Jur"); // true
13parkName.endsWith("Park"); // true
14parkName.includes("assic"); // true
15
16// Zmiana wielkości liter
17parkName.toUpperCase(); // "JURASSIC PARK"
18parkName.toLowerCase(); // "jurassic park"
19
20// Wycinanie fragmentów
21parkName.substring(0, 8); // "Jurassic"
22parkName.slice(-4); // "Park" (liczy od końca)
23
24// Zastępowanie fragmentów
25parkName.replace("Jurassic", "Dinosaur"); // "Dinosaur Park"
26
27// Podział stringa na tablicę
28parkName.split(" "); // ["Jurassic", "Park"]
29
30// Usuwanie białych znaków
31" Danger Zone ".trim(); // "Danger Zone"
32
33// Łączenie stringów
34"Welcome".concat(" to ", parkName); // "Welcome to Jurassic Park"
35
36// Powtarzanie stringa
37"Roar! ".repeat(3); // "Roar! Roar! Roar! "Operacje na Liczbach
JavaScript oferuje wiele możliwości pracy z liczbami, zarówno bezpośrednio na wartościach, jak i przez obiekt Math:
1// Podstawowe operacje arytmetyczne
25 + 3; // 8 (dodawanie)
35 - 3; // 2 (odejmowanie)
45 * 3; // 15 (mnożenie)
55 / 3; // 1.6666666666666667 (dzielenie)
65 % 3; // 2 (modulo - reszta z dzielenia)
75 ** 3; // 125 (potęgowanie - 5 do potęgi 3)
8
9// Inkrementacja i dekrementacja
10let dinoCount = 5;
11dinoCount++; // dinoCount jest teraz 6
12dinoCount--; // dinoCount z powrotem do 5
13
14// Operatory przypisania i operacji
15dinoCount += 3; // To samo co: dinoCount = dinoCount + 3
16dinoCount *= 2; // To samo co: dinoCount = dinoCount * 2
17
18// Obiekt Math do zaawansowanych operacji
19Math.abs(-5); // 5 (wartość bezwzględna)
20Math.round(4.7); // 5 (zaokrąglenie do najbliższej liczby całkowitej)
21Math.ceil(4.1); // 5 (zaokrąglenie w górę)
22Math.floor(4.9); // 4 (zaokrąglenie w dół)
23Math.max(3, 7, 2, 4); // 7 (znajdowanie maksimum)
24Math.min(3, 7, 2, 4); // 2 (znajdowanie minimum)
25Math.pow(2, 3); // 8 (potęgowanie - 2 do potęgi 3)
26Math.sqrt(16); // 4 (pierwiastek kwadratowy)
27Math.sin(0); // 0 (sinus)
28Math.cos(0); // 1 (cosinus)
29Math.random(); // Losowa liczba od 0 (włącznie) do 1 (wyłącznie)
30
31// Generowanie losowej liczby z zakresu
32function getRandom(min, max) {
33 return Math.floor(Math.random() * (max - min + 1)) + min;
34}
35getRandom(1, 10); // Losowa liczba od 1 do 10
36
37// Formatowanie liczb
38const height = 5.678934;
39height.toFixed(2); // "5.68" (dwa miejsca po przecinku, zwraca string)
40height.toPrecision(3); // "5.68" (trzy znaczące cyfry, zwraca string)
41height.toString(2); // "101.1010110111001110100111100101111000100100011110001" (reprezentacja binarna)
42(1234567).toLocaleString(); // "1,234,567" (formatowanie z separatorami, zależy od locale)Operacje na Wartościach Logicznych
Chociaż typ boolean ma tylko dwie możliwe wartości, istnieje wiele operacji logicznych:
1// Operatory porównania
25 > 3; // true (większe niż)
35 >= 5; // true (większe lub równe)
43 < 5; // true (mniejsze niż)
53 <= 3; // true (mniejsze lub równe)
65 == "5"; // true (równość nieścisła - różne typy są konwertowane)
75 === "5"; // false (równość ścisła - typy muszą być zgodne)
85 != "6"; // true (nierówność nieścisła)
95 !== "5"; // true (nierówność ścisła)
10
11// Operatory logiczne
12true && true; // true (AND logiczne - oba warunki muszą być prawdziwe)
13true && false; // false
14true || false; // true (OR logiczne - co najmniej jeden warunek musi być prawdziwy)
15false || false; // false
16!true; // false (NOT logiczne - negacja)
17!false; // true
18
19// Złożone warunki
20const isSafe = fenceActive && powerLevel > 5000 && !stormApproaching;
21const needsEvacuation = alarmTriggered || dinoEscaped || stormStrength > 8;Operacje na null i undefined
Pomimo ograniczonych możliwości bezpośrednich operacji na null i undefined, istnieją użyteczne wzorce pracy z nimi:
1// Operator || do wartości domyślnych (uwaga: zastąpi też 0 i pusty string)
2const visitorName = userName || "Gość"; // Użycie userName, jeśli istnieje, w przeciwnym razie "Gość"
3
4// Operator nullish coalescing (??) - dostępny w nowszych wersjach JS
5const count = dinoCount ?? 0; // Użycie dinoCount, jeśli nie jest null/undefined, w przeciwnym razie 0
6
7// Optional chaining (?.) - dostępny w nowszych wersjach JS
8const species = dinosaur?.species; // Bezpieczny dostęp do właściwości, nawet jeśli dinosaur jest null/undefinedCiekawe i trudne przypadki konwersji typów
Niektóre konwersje typów w JavaScript mogą być zaskakujące, podobnie jak nietypowe zachowania dinozaurów po burzy:
1// Dziwne przypadki równości nieścisłej (==)
2[] == ''; // true (pusta tablica jest konwertowana na pusty string)
3[1] == 1; // true (tablica [1] jest konwertowana na string "1", a potem na liczbę 1)
4[1, 2] == '1,2'; // true (tablica [1, 2] jest konwertowana na string "1,2")
5true == '1'; // true (true jest konwertowane na 1, a '1' na 1)
6false == '0'; // true (false jest konwertowane na 0, a '0' na 0)
7null == undefined; // true (specjalny przypadek w specyfikacji)
8'' == 0; // true (pusty string jest konwertowany na 0)
9
10// Operacje z NaN
11NaN == NaN; // false (NaN nie jest równe niczemu, nawet samemu sobie)
12Number.isNaN(NaN); // true (właściwy sposób sprawdzania NaN)
13
14// Operacje z obiektami
15const obj1 = {}, obj2 = {};
16obj1 == obj2; // false (obiekty są porównywane przez referencję, nie zawartość)
17obj1 === obj2; // false (obiekty są porównywane przez referencję, nie zawartość)
18
19// Operacje na tablicach
20[] + []; // "" (tablice są konwertowane na stringi, a potem łączone)
21[] + {}; // "[object Object]" (obiekt jest konwertowany na string)
22{} + []; // 0 (puste {} jest traktowane jako blok kodu, a +[] jest konwertowane na liczbę)Najlepsze praktyki
Aby uniknąć niespodzianek przy pracy z typami danych, warto stosować następujące zasady - są jak protokoły bezpieczeństwa w Parku Jurajskim:
1. Używaj ścisłego porównania (===, !==)
1// ŹLE
2if (dinoCount == "5") { // Zadziała, ale może prowadzić do błędów
3
4// DOBRZE
5if (dinoCount === 5) { // Wyraźnie wskazuje, że dinoCount powinno być liczbą2. Jawnie konwertuj typy, gdy jest to potrzebne
1// ŹLE
2const totalVisitors = visitorCount + newVisitors; // Może dawać niepoprawne wyniki, jeśli któraś zmienna jest stringiem
3
4// DOBRZE
5const totalVisitors = Number(visitorCount) + Number(newVisitors); // Jawna konwersja na liczby3. Używaj odpowiednich metod sprawdzania typu
1// ŹLE
2if (typeof height == "number" && !isNaN(height)) { // Działa, ale jest nieprecyzyjne
3
4// DOBRZE
5function isValidNumber(value) {
6 return typeof value === 'number' && !isNaN(value) && isFinite(value);
7}
8if (isValidNumber(height)) {4. Uważaj na operacje na obiektach
1// ŹLE
2if (dinosaur == otherDinosaur) { // Porównuje referencje, nie zawartość
3
4// DOBRZE
5function isEqual(obj1, obj2) {
6 return JSON.stringify(obj1) === JSON.stringify(obj2); // Dla prostych obiektów
7}
8if (isEqual(dinosaur, otherDinosaur)) {5. Używaj operatorów nullish coalescing (??) i optional chaining (?.)
1// ZAMIAST
2const safeVisitorCount = visitorCount !== null && visitorCount !== undefined ? visitorCount : 0;
3const speciesName = dinosaur && dinosaur.species ? dinosaur.species : "Nieznany";
4
5// LEPIEJ (w nowszym JS)
6const safeVisitorCount = visitorCount ?? 0;
7const speciesName = dinosaur?.species ?? "Nieznany";Praktyczny przykład: Przetwarzanie danych o dinozaurach
Poniższy przykład pokazuje, jak zastosować operacje na typach danych w praktycznym scenariuszu:
1// Dane przychodzące z różnych źródeł (symulacja API, formularzy, plików CSV)
2const rawDinoData = [
3 { id: "1", name: "Rexy", species: "T-Rex", height: "5.6", dangerous: "true", lastFed: "2023-05-15T08:30:00" },
4 { id: 2, name: "Blue", species: "Velociraptor", height: "1.8", dangerous: true, lastFed: "2023-05-15T09:15:00" },
5 { id: "3", name: "Spike", species: "Stegosaurus", height: 4.2, dangerous: "false", lastFed: null },
6 { id: "4", name: "Cera", species: "Triceratops", height: "unknown", dangerous: false, lastFed: "invalid-date" }
7];
8
9// Funkcja do normalizacji i walidacji danych
10function processDinosaurData(dinoList) {
11 // Przygotowanie znormalizowanej tablicy
12 const processedData = [];
13
14 // Przetworzenie każdego elementu
15 for (let i = 0; i < dinoList.length; i++) {
16 const dino = dinoList[i];
17
18 // Normalizacja ID
19 const id = Number(dino.id);
20 if (isNaN(id) || id <= 0) {
21 console.warn(`Pominięto dinozaura z nieprawidłowym ID: ${dino.id}`);
22 continue;
23 }
24
25 // Normalizacja imienia
26 const name = String(dino.name).trim();
27 if (name === "") {
28 console.warn(`Pominięto dinozaura bez imienia, ID: ${id}`);
29 continue;
30 }
31
32 // Normalizacja gatunku
33 const species = String(dino.species).trim() || "Nieznany";
34
35 // Normalizacja wysokości
36 let height;
37 if (dino.height === "unknown" || dino.height === undefined) {
38 height = null;
39 } else {
40 height = Number(dino.height);
41 if (isNaN(height)) {
42 console.warn(`Nieprawidłowa wysokość dla ${name}, ustawiono null`);
43 height = null;
44 }
45 }
46
47 // Normalizacja flagi niebezpieczny
48 let dangerous;
49 if (typeof dino.dangerous === 'string') {
50 dangerous = dino.dangerous.toLowerCase() === 'true';
51 } else {
52 dangerous = Boolean(dino.dangerous);
53 }
54
55 // Normalizacja daty ostatniego karmienia
56 let lastFed = null;
57 if (dino.lastFed) {
58 const date = new Date(dino.lastFed);
59 if (!isNaN(date.getTime())) {
60 lastFed = date;
61 } else {
62 console.warn(`Nieprawidłowa data karmienia dla ${name}`);
63 }
64 }
65
66 // Dodatkowe obliczenia
67 const securityLevel = dangerous ? (height > 3 ? "Wysoki" : "Średni") : "Niski";
68 const daysFromLastFeed = lastFed ? Math.floor((new Date() - lastFed) / (1000 * 60 * 60 * 24)) : null;
69
70 // Dodanie znormalizowanego dinozaura do wynikowej tablicy
71 processedData.push({
72 id,
73 name,
74 species,
75 height,
76 dangerous,
77 lastFed,
78 securityLevel,
79 daysFromLastFeed,
80 needsFeeding: daysFromLastFeed === null || daysFromLastFeed > 1
81 });
82 }
83
84 return processedData;
85}
86
87// Używanie funkcji
88const normalizedDinos = processDinosaurData(rawDinoData);
89console.log(normalizedDinos);
90
91// Dodatkowe przetwarzanie danych
92const dangerousDinos = normalizedDinos.filter(dino => dino.dangerous);
93const withHeight = normalizedDinos.filter(dino => dino.height !== null);
94const avgHeight = withHeight.reduce((sum, dino) => sum + dino.height, 0) / withHeight.length;
95const dinosBySecurityLevel = normalizedDinos.reduce((groups, dino) => {
96 groups[dino.securityLevel] = groups[dino.securityLevel] || [];
97 groups[dino.securityLevel].push(dino);
98 return groups;
99}, {});Ten przykład pokazuje, jak radzić sobie z różnymi typami danych, konwertować je, walidować i normalizować - wszystko to są podstawowe operacje, których naukowcy w Parku Jurajskim musieliby dokonywać na codziennych danych.
Podsumowanie
Konwersja typów i operacje na typach danych w JavaScript to obszerne zagadnienie, które wymaga zrozumienia wielu niuansów. Kluczowe aspekty to:
Niejawna konwersja - JavaScript automatycznie konwertuje typy w wielu kontekstach
- Może prowadzić do nieoczekiwanych wyników
- Jest wygodna, ale czasem niebezpieczna
Jawna konwersja - Kontrolowane przekształcanie typów
String(),Number(),Boolean()- funkcje konwertującetoString(),parseInt(),parseFloat()- metody i funkcje specjalizowane!!- szybka konwersja na boolean
Operacje na poszczególnych typach
- Stringi mają bogaty zestaw metod do manipulacji tekstem
- Liczby mogą być przetwarzane przy użyciu operatorów i obiektu Math
- Wartości logiczne są podstawą dla instrukcji warunkowych
- Null i undefined mają specjalne zasady w operacjach
Najlepsze praktyki
- Używanie ścisłego porównania (===, !==)
- Jawne konwertowanie typów tam, gdzie to potrzebne
- Stosowanie odpowiednich funkcji sprawdzających
Podobnie jak w Parku Jurajskim, gdzie różne gatunki dinozaurów wymagają różnych protokołów postępowania, tak w JavaScript różne typy danych wymagają odpowiedniego podejścia. Znajomość zasad konwersji i operacji na typach pozwala na skuteczne i bezpieczne manipulowanie danymi - podstawę każdej aplikacji JavaScript.
W następnej lekcji przyjrzymy się operatorom arytmetycznym i przypisania, które pozwalają na przeprowadzanie bardziej zaawansowanych kalkulacji - niezbędnych dla zarządzania zasobami w tak złożonym przedsięwzięciu jak Park Jurajski.
Kod do tej lekcji: index.js
1// Konwersja typów i operacje na typach danych
2// Eksperymentuj z niejawna i jawna konwersja typów w JavaScript
3
4// === Niejawna konwersja (Type Coercion) ===
5console.log("=== Niejawna konwersja ===");
6
7// String + Number -> konkatenacja
8console.log("Dinozaurów: " + 5); // "Dinozaurów: 5"
9console.log("5" + 3); // "53" (string!)
10
11// String - Number -> Number
12console.log("10" - 3); // 7
13console.log("5" * 2); // 10
14
15// Boolean w operacjach
16console.log(true + 1); // 2
17console.log(false + 1); // 1
18
19// === Jawna konwersja ===
20console.log("\n=== Jawna konwersja ===");
21
22// Na Number
23console.log(Number("42")); // 42
24console.log(Number("abc")); // NaN
25console.log(parseInt("100px")); // 100
26console.log(parseFloat("3.14m")); // 3.14
27
28// Na String
29console.log(String(42)); // "42"
30console.log(String(true)); // "true"
31console.log((255).toString(16)); // "ff" (hex)
32
33// Na Boolean
34console.log(Boolean(0)); // false
35console.log(Boolean("")); // false
36console.log(Boolean("tekst")); // true
37console.log(Boolean(1)); // true
38
39// === typeof operator ===
40console.log("\n=== typeof ===");
41console.log(typeof 42); // "number"
42console.log(typeof "tekst"); // "string"
43console.log(typeof true); // "boolean"
44console.log(typeof undefined); // "undefined"
45console.log(typeof null); // "object" (historyczny bug!)
46
47// Twoje zadanie:
48// 1. Sprawdź wynik "5" + 3 vs "5" - 3
49// 2. Użyj Number() do konwersji stringa na liczbę
50// 3. Sprawdź typeof dla różnych wartości
51Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Co zwróci wyrażenie Number('hello') w JavaScript?
2. Co zwróci wyrażenie '5' - 2 w JavaScript?
3. Która metoda jawnej konwersji stringa na liczbę jest NIEPOPRAWNA?
4. Która z poniższych wartości NIE jest wartością falsy w JavaScript?
Zadania praktyczne w grze
- Układanie w poziomie
Ułóż elementy template literal: