Lekcja 2: Zmienne i Typy Danych

W tej lekcji poznasz podstawowe elementy języka JavaScript - zmienne oraz typy danych. Zrozumienie tych koncepcji jest kluczowe dla dalszej nauki programowania.

Zmienne w JavaScript

Zmienne to podstawowe "pojemniki" na dane w programowaniu. Pozwalają na przechowywanie wartości, które można później wykorzystać lub zmodyfikować w programie.

Deklarowanie zmiennych

W JavaScript mamy trzy sposoby deklarowania zmiennych:

// Używając var (starszy sposób, rzadziej używany w nowoczesnym JS)
var imie = "Jan";

// Używając let (wprowadzone w ES6, zalecane dla zmiennych, których wartość może się zmieniać)
let wiek = 25;

// Używając const (wprowadzone w ES6, dla stałych wartości, których nie będziemy zmieniać)
const PI = 3.14159;

Różnice między var, let i const

Przykład różnic w zasięgu:

function przykladFunkcji() {
    if (true) {
        var zmiennaVar = "Jestem var";
        let zmiennaLet = "Jestem let";
        const zmiennaConst = "Jestem const";
    }
    
    console.log(zmiennaVar);    // Zadziała - "Jestem var"
    // console.log(zmiennaLet);    // Błąd - zmiennaLet is not defined
    // console.log(zmiennaConst);  // Błąd - zmiennaConst is not defined
}
przykladFunkcji(); // Wywołanie funkcji, aby zobaczyć wynik

Zasady nazywania zmiennych

Typy danych w JavaScript

JavaScript jest językiem dynamicznie typowanym, co oznacza, że nie musimy deklarować typu zmiennej - jest on określany automatycznie na podstawie przypisanej wartości.

Typy prymitywne

  1. String - ciąg znaków, tekst
  2. Number - liczby (całkowite i zmiennoprzecinkowe)
  3. Boolean - wartości logiczne (true/false)
  4. Undefined - zmienna zadeklarowana, ale bez przypisanej wartości
  5. Null - specjalna wartość oznaczająca "nic" lub "puste"
  6. Symbol - unikalny i niezmienny identyfikator (wprowadzony w ES6)
  7. BigInt - do reprezentowania bardzo dużych liczb całkowitych (wprowadzony w ES2020)

Przykłady typów prymitywnych

// String
let imie = "Anna";
let nazwisko = 'Kowalska';  // Można używać pojedynczych lub podwójnych cudzysłowów
let tekst = `Witaj, ${imie}!`;  // Template literals (ES6) - pozwalają na wstawianie zmiennych w tekst

// Number
let wiek = 25;          // Liczba całkowita
let wzrost = 1.75;      // Liczba zmiennoprzecinkowa
let nieskonczonosc = Infinity;  // Specjalna wartość: nieskończoność
let nieNumer = NaN;     // Not a Number - specjalna wartość oznaczająca nieprawidłową operację matematyczną

// Boolean
let czyPelnoletni = true;
let czyZalogowany = false;

// Undefined
let nieprzypisanaZmienna;
console.log(nieprzypisanaZmienna);  // undefined

// Null
let pustaWartosc = null;

// Symbol
let symbol1 = Symbol("opis");
let symbol2 = Symbol("opis");
console.log(symbol1 === symbol2);  // false - każdy Symbol jest unikalny

// BigInt
let duzaLiczba = 9007199254740991n;  // Dodanie 'n' na końcu tworzy BigInt

Typ złożony: Object

Oprócz typów prymitywnych, JavaScript ma jeden typ złożony - Object. Obiekty mogą przechowywać kolekcje danych i bardziej złożone encje.

Przykłady obiektów:

// Obiekt (kolekcja par klucz-wartość)
let osoba = {
    imie: "Jan",
    nazwisko: "Kowalski",
    wiek: 30,
    przedstawSie: function() {
        return `Nazywam się ${this.imie} ${this.nazwisko}`;
    }
};

// Tablica (specjalny rodzaj obiektu do przechowywania uporządkowanych kolekcji)
let kolory = ["czerwony", "zielony", "niebieski"];

// Data (wbudowany obiekt do pracy z datami)
let dzisiaj = new Date();

Sprawdzanie typu zmiennej

Do sprawdzenia typu zmiennej możemy użyć operatora typeof:

let tekst = "Hello";
let liczba = 42;
let prawda = true;
let tablica = [1, 2, 3];
let obiekt = { klucz: "wartość" };
let nieprzypisana;
let pustaWartosc = null;

console.log(typeof tekst);        // "string"
console.log(typeof liczba);       // "number"
console.log(typeof prawda);       // "boolean"
console.log(typeof tablica);      // "object" (uwaga: tablice są obiektami w JS)
console.log(typeof obiekt);       // "object"
console.log(typeof nieprzypisana); // "undefined"
console.log(typeof pustaWartosc); // "object" (uwaga: to jest znany błąd w JS)

Konwersja typów

JavaScript często automatycznie konwertuje typy danych, co może prowadzić do nieoczekiwanych wyników:

// Konwersja do String
let liczba = 42;
let tekstLiczby = String(liczba);  // Jawna konwersja
let tekstLiczby2 = liczba + "";    // Niejawna konwersja

// Konwersja do Number
let tekst = "42";
let liczbaZTekstu = Number(tekst);  // Jawna konwersja
let liczbaZTekstu2 = +tekst;        // Niejawna konwersja używając operatora +
let liczbaZTekstu3 = parseInt(tekst, 10);  // Parsowanie do liczby całkowitej (drugi parametr to system liczbowy)

// Konwersja do Boolean
let wartosc = "hello";
let logiczna = Boolean(wartosc);  // Jawna konwersja
let logiczna2 = !!wartosc;        // Niejawna konwersja używając podwójnej negacji

Warto wiedzieć, które wartości są konwertowane na false (tzw. "falsy values"):

Wszystkie inne wartości są konwertowane na true.

Zadanie praktyczne

Stwórz zmienne różnych typów reprezentujące informacje o studencie: imię, nazwisko, wiek, czy zdał ostatni egzamin, listę ocen oraz obiekt zawierający adres. Następnie wyświetl wszystkie te informacje w konsoli wraz z ich typami.

Pokaż rozwiązanie
// Deklaracja zmiennych różnych typów
let imie = "Anna";
let nazwisko = "Nowak";
let wiek = 22;
let czyZdalEgzamin = true;
let oceny = [4, 5, 3, 5, 4];
let adres = {
    ulica: "Kwiatowa",
    numer: 15,
    miasto: "Warszawa",
    kodPocztowy: "00-001"
};

// Wyświetlenie informacji w konsoli
console.log("Imię:", imie, "- typ:", typeof imie);
console.log("Nazwisko:", nazwisko, "- typ:", typeof nazwisko);
console.log("Wiek:", wiek, "- typ:", typeof wiek);
console.log("Czy zdał egzamin:", czyZdalEgzamin, "- typ:", typeof czyZdalEgzamin);
console.log("Oceny:", oceny, "- typ:", typeof oceny);
console.log("Adres:", adres, "- typ:", typeof adres);

// Dodatkowe wyświetlenie szczegółów adresu
console.log("Szczegóły adresu:");
console.log(`${adres.ulica} ${adres.numer}, ${adres.kodPocztowy} ${adres.miasto}`);

Zadanie do samodzielnego wykonania

Stwórz skrypt, który demonstruje różnice między var, let i const. Spróbuj:

  1. Zadeklarować zmienną każdego typu i przypisać jej wartość
  2. Zmienić wartość każdej zmiennej
  3. Zadeklarować ponownie każdą zmienną
  4. Stworzyć blok kodu (używając nawiasów klamrowych {}) i wewnątrz niego zadeklarować zmienne każdego typu, a następnie spróbować uzyskać do nich dostęp poza blokiem

Obserwuj, które operacje zakończą się sukcesem, a które błędem.

FAQ - Zmienne i Typy Danych

Kiedy używać let, a kiedy const?

Używaj const jako domyślnego wyboru dla wszystkich zmiennych, których wartość nie będzie się zmieniać. Używaj let tylko wtedy, gdy wiesz, że wartość zmiennej będzie modyfikowana. Takie podejście pomaga uniknąć przypadkowych zmian wartości i czyni kod bardziej przewidywalnym.

Czy mogę zmienić zawartość tablicy lub obiektu zadeklarowanego przez const?

Tak. Deklaracja const zapobiega ponownemu przypisaniu zmiennej, ale nie chroni przed modyfikacją zawartości obiektów i tablic. Możesz dodawać, usuwać i modyfikować właściwości obiektów oraz elementy tablic zadeklarowanych przez const.

Dlaczego typeof null zwraca "object"?

To jest historyczny błąd w JavaScript, który nigdy nie został naprawiony ze względu na kompatybilność wsteczną. W pierwszej implementacji JS, wartości były reprezentowane jako 32-bitowe wartości, gdzie pierwsze 3 bity oznaczały typ. Typ "object" miał znacznik 000, a null był po prostu wskaźnikiem zerowym (0x00), więc również miał wszystkie bity ustawione na 0.

Jaka jest różnica między null a undefined?

undefined oznacza, że zmienna została zadeklarowana, ale nie przypisano jej wartości. null to wartość, którą programista jawnie przypisuje zmiennej, aby wskazać "brak wartości" lub "pustą wartość". undefined jest wartością domyślną, null musi być przypisany celowo.

Czy JavaScript ma silne typowanie?

Nie, JavaScript jest językiem o słabym (dynamicznym) typowaniu. Oznacza to, że zmienne nie mają określonego typu, a ich typ może się zmieniać w trakcie wykonywania programu. JavaScript automatycznie konwertuje typy danych w zależności od kontekstu, co może prowadzić do nieoczekiwanych wyników.

Co to jest hoisting w kontekście zmiennych?

Hoisting to zachowanie JavaScript, gdzie deklaracje zmiennych i funkcji są "podnoszone" na górę ich zakresu przed wykonaniem kodu. Zmienne zadeklarowane przez var są hoistowane i inicjalizowane jako undefined, podczas gdy zmienne let i const są hoistowane, ale nie inicjalizowane (pozostają w "temporal dead zone").

Jak sprawdzić, czy zmienna jest tablicą?

Operator typeof zwraca "object" dla tablic, co nie pozwala odróżnić ich od innych obiektów. Aby sprawdzić, czy zmienna jest tablicą, użyj metody Array.isArray(zmienna), która zwraca true dla tablic i false dla innych typów.