Moduł 1 · Podstawy JavaScript
Zmienne: let, const i var
Wyobraź sobie, że piszesz aplikację e-commerce. Potrzebujesz przechowywać dane klienta, ceny produktów i stany koszyka. Które zmienne powinny być stałe, a które mogą się zmieniać? Ta lekcja nauczy Cię podejmować właściwe decyzje.
Dlaczego sposób deklarowania zmiennych ma znaczenie?
W JavaScript każda zmienna to pudełko z etykietą, ale rodzaj pudełka wpływa na to, jak możesz je później używać. Wybór między const, let i var to nie kwestia stylu — to decyzja wpływająca na bezpieczeństwo i czytelność kodu.
Według statystyk GitHub, w nowoczesnym kodzie JavaScript aż 78% zmiennych deklarowanych jest przez const, 20% przez let, a zaledwie 2% przez var.
const — Twój domyślny wybór
Słowo const tworzy referencję niezmienną. Oznacza to, że nie możesz przypisać nowej wartości, ale zawartość obiektu może się zmieniać:
const NAZWA_FIRMY = "DevShop";
const STAWKA_VAT = 0.23;
const KOLORY_MARKI = ["#007bff", "#6c757d", "#28a745"];
// NAZWA_FIRMY = "NowaFirma"; // TypeError!Praktyczny przykład z e-commerce:
const produkt = {
id: 1,
nazwa: "Laptop",
cena: 2999
};
// Możesz zmieniać właściwości
produkt.cena = 2799; // Promocja - OK!
produkt.dostepny = true; // Dodawanie właściwości - OK!
// Ale nie możesz zastąpić całego obiektu
// produkt = {}; // TypeError!Wskazówka: Używaj WIELKICH_LITER dla stałych konfiguracyjnych (API_URL, MAX_ITEMS), a camelCase dla obiektów i tablic (
const userPreferences).
let — gdy wartość musi się zmienić
let to narzędzie do zmiennych dynamicznych z zasięgiem blokowym:
let koszyk = [];
let łącznaWartość = 0;
let statusZamówienia = "oczekujący";
for (let i = 0; i < produkty.length; i++) {
łącznaWartość += produkty[i].cena;
}
if (łącznaWartość > 500) {
statusZamówienia = "darmowa dostawa";
}Zasięg blokowy oznacza, że zmienna istnieje tylko w klamrach {}:
function przetwórzZamówienie() {
let komunikat;
if (koszyk.length > 0) {
let rabat = obliczRabat(); // Istnieje tylko w tym if
komunikat = `Oszczędzasz ${rabat} zł`;
}
// console.log(rabat); // ReferenceError - poza zasięgiem!
return komunikat;
}var — dlaczego go unikać?
var ma zasięg funkcyjny i jest wynoszony (hoisted), co prowadzi do nieprzewidywalnych błędów:
function problemZVar() {
console.log(x); // undefined (nie błąd!)
if (true) {
var x = "niespodziewane zachowanie";
}
console.log(x); // "niespodziewane zachowanie" - var "wyciekł" z if!
}Realny problem w pętlach:
// Źle - z var
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // Wypisze: 3, 3, 3
}
// Dobrze - z let
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // Wypisze: 0, 1, 2
}Temporal Dead Zone (TDZ)
Zmienne let i const mają specjalną ochronę - istnieją, ale są niedostępne do momentu deklaracji:
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 5;
console.log(b); // undefined (var ma inne zachowanie)
var b = 10;Wskazówka: TDZ pomaga wyłapać błędy logiczne. Jeśli próbujesz użyć zmiennej przed jej deklaracją, prawdopodobnie masz błąd w strukturze kodu.
Praktyczne zastosowania
W komponencie React:
const UserProfile = () => {
const API_URL = "https://api.example.com"; // Stała konfiguracyjna
let loadingState = false; // Stan może się zmienić
const [userData, setUserData] = useState({}); // Hook React
// Funkcja pomocnicza
const fetchUserData = async () => {
loadingState = true;
// logika pobierania danych...
};
};Podsumowanie zasad:
- Zawsze zaczynaj od
const- to najbezpieczniejszy wybór - Zmień na
lettylko gdy wartość musi się zmienić - Nigdy nie używaj
varw nowym kodzie ES6+ - Używaj opisowych nazw zamiast skrótów (długośćTekstu zamiast dt)
- WIELKIE_LITERY dla stałych konfiguracyjnych