Zmienne: var, let, const
Zmienne to podstawowy mechanizm przechowywania danych w programie. W JavaScript zmienne deklarujemy za pomocą słów kluczowych var, let lub const. Każde z nich ma trochę inne właściwości i zasady działania:
var: historycznie jedyny sposób deklarowania zmiennych w JS (przed rokiem 2015). Zmienne zadeklarowane przezvarmają zasięg funkcyjny lub globalny, co oznacza, że jeśli zadeklarujesz zmiennąvarwewnątrz funkcji, będzie ona dostępna w całej tej funkcji (ale nie poza nią), a jeśli poza jakąkolwiek funkcją – stanie się zmienną globalną.varpozwala też na ponowną deklarację tej samej zmiennej (co bywa źródłem błędów). Przykład:
var x = 1; if (true) {
var x = 2; // to tak naprawdę ta sama zmienna x (zasięg funkcji lub globalny)
console.log(x); // wypisze 2
}
console.log(x); // też wypisze 2, bo blok if nie tworzy nowego zakresu dla var
W dzisiejszych czasach var jest rzadziej używany – zastąpiły go let i const – ale warto znać, bo w starych skryptach JS wciąż go spotkasz.
let: wprowadzony w ES6 (2015) sposób deklarowania zmiennych o zasięgu blokowym. Oznacza to, że zmienna zadeklarowana poprzezletistnieje tylko wewnątrz bloku{ }, w którym ją umieszczono (lub całego skryptu, jeśli na najwyższym poziomie). Nie można dwukrotnie zadeklarować zmiennej o tej samej nazwie w tym samym bloku.letjest zalecanym sposobem deklaracji zmiennych, gdyż ogranicza ich zakres, co zmniejsza ryzyko niechcącego nadpisania wartości. Przykład:
let y = 5;
if (true) { let y = 10; // to inna zmienna y, istniejąca tylko w tym bloku if
console.log(y); // 10 } console.log(y); // 5 (oryginalna zmienna y pozostała nietknięta)
const: również wprowadzony w ES6, służy do deklaracji stałych. Zmienna zadeklarowana jakoconsttakże ma zasięg blokowy jaklet, ale dodatkowo nie można zmienić przypisanej do niej wartości (przynajmniej jeśli chodzi o proste typy). Próba ponownego przypisania doconstspowoduje błąd. Np.:
const PI = 3.14159; PI = 3.14; // BŁĄD: nie można zmienić wartości stałej
Ważna uwaga: jeśli const wskazuje na obiekt lub tablicę, sama referencja jest stała, ale zawartość obiektu/elementy tablicy można zmieniać. Czyli
const osoba = { imie: "Jan" };
nie pozwoli przypisać osoba = 5, ale można zrobić osoba.imie = "Adam" wewnątrz tego obiektu.
Podsumowując: używaj let do zmiennych, których wartość będzie się zmieniać, a const do wartości stałych lub zmiennych, które nie powinny być ponownie przypisane. var generalnie nie jest zalecany, chyba że istnieje specjalna potrzeba lub pracujemy w starym kodzie. Ze względu na zasięg blokowy let/const oraz ich bardziej przewidywalne zachowanie, większość nowych projektów w JS trzyma się tej pary. Wiele stylów kodowania wręcz sugeruje, by domyślnie używać const, a tylko wtedy gdy potrzebujemy zmienność – użyć let.
Podstawowe typy danych
JavaScript jest językiem dynamicznie typowanym, co oznacza, że zmienna może przechowywać wartość dowolnego typu i można jej przypisać inną wartość (nawet innego typu) w trakcie działania programu. Nie musimy deklarować typu zmiennej – interpreter sam rozpoznaje typ wartości przypisanej. To elastyczne podejście: ta sama zmienna może np. najpierw przechowywać liczbę, a potem string, i nie spowoduje to błędu (choć w praktyce należy uważać, by nie mieszać typów w niekontrolowany sposób).
Jakie są typy danych w JavaScript? Standard ECMAScript definiuje kilka podstawowych typów. Możemy podzielić je na typy proste (prymitywne) oraz typ złożony:
- Liczby (
number): reprezentują zarówno liczby całkowite, jak i zmiennoprzecinkowe. W JavaScript wszystkie liczby (poza BigInt) są typunumberi są przechowywane w formacie 64-bitowego zmiennoprzecinkowego (IEEE 754). Przykłady:42,3.14,-0.5. Istnieją też specjalne wartości jakNaN(Not a Number) iInfinity/-Infinity. Nie ma osobnych typów dla int/float – to wszystkonumber. Do operacji arytmetycznych używamy zwykłych operatorów (+,-,*,/,%). - Napisy tekstowe (
string): ciągi znaków ujęte w cudzysłowy (pojedyncze'...'lub podwójne"...") albo backticki`...`(te ostatnie tworzą szablony stringów pozwalające wstawiać zmienne). String może być pusty ("") lub bardzo długi, może zawierać dowolne symbole (w Unicode). Przykłady:"Hello",' świat',`Wynik = ${x+y}`. - Wartości logiczne (
boolean): przyjmują jedną z dwóch wartości:true(prawda) lubfalse(fałsz). Używane są w warunkach, pętlach i wszędzie tam, gdzie potrzebna jest ocena prawda/fałsz. null: specjalna wartość oznaczająca brak wartości. W praktycenullczęsto jest używany gdy chcemy świadomie wskazać, że „tu nic nie ma”. Np. zmienna może byćnullgdy nie została jeszcze zainicjalizowana konkretnym obiektem.undefined: inna szczególna wartość, która oznacza, że zmienna została zdefiniowana, ale nie przypisano do niej jeszcze żadnej wartości. Każda nowo zadeklarowana zmienna (bez inicjalizacji) ma domyślnie wartośćundefined. Przykład: jsKopiujEdytujlet z; console.log(z); // undefined, bo nic jeszcze nie przypisano- Obiekty (
object): to typ złożony. Obejmuje wszystko, co nie jest żadnym z powyższych typów prymitywnych. Obiektem jest zarówno zwykła struktura klucz-wartość (literał obiektowy{}), jak i tablice, funkcje, daty, ekspresje regularne itd. Obiekty w JS można traktować jak dynamiczne słowniki/rekordy – mogą posiadać właściwości (pola) i metody. Np. obiekt osoba: jsKopiujEdytujlet osoba = { imie: "Jan", wiek: 30 }; console.log(osoba.imie); // "Jan"będzie typu object. Tablica[]jest również szczególnym przypadkiem obiektu (ma indeksy liczbowe jako klucze i specjalne właściwości, np. długość). Funkcje też są obiektami (tzw. obiekty funkcyjne), co jest istotne, bo można je przekazywać jak dane. BigInt: to nowszy (dodany w ES2020) typ prymitywny służący do reprezentowania bardzo dużych liczb całkowitych, które nie mieszczą się w zwykłym typienumber. BigInt zapisujemy jako liczba z literąnna końcu, np.12345678901234567890n. Dla początkujących ten typ rzadko będzie potrzebny, ale warto wiedzieć, że istnieje, gdy operujemy na ogromnych liczbach (np. kryptografia).Symbol: kolejny mniej typowy prymitywny typ (dodany w ES2015). Symbol to unikalna, niezmienialna wartość, często używana jako unikalny klucz w obiektach lub do tzw. symboli globalnych. Symbole tworzy się za pomocąSymbol("opis"). Na wczesnym etapie nauki raczej się z nimi nie spotkasz – to zaawansowany koncept, używany głównie we wnętrzu bibliotek czy do specjalnych przypadków (np. definiowanie własnego iteratora obiektu).
Zwykle w codziennym kodowaniu najczęściej operujemy na: number, string, boolean, null/undefined i object (w tym array). Typy BigInt i Symbol pojawiają się rzadziej. Warto jeszcze raz podkreślić: JavaScript jest dynamicznie typowany, co daje elastyczność, ale wymaga ostrożności. Możemy np. dodać liczbę do stringa, co spowoduje nie arytmetykę, a konkatenację (połączenie w string) – JS automatycznie konwertuje typy w niektórych sytuacjach. Przykład:
let wynik = "2" + 3; // wynik = "23" (3 zostaje zamienione na "3" i dopisane do "2")
let suma = "2" * 3; // wynik = 6 ("2" zostaje zamienione na 2 i mnożenie działa)
Takie zachowanie może czasem zaskakiwać. Dlatego programując w JS, staramy się pilnować, jakiego typu dane przekazujemy do operacji, albo jawnie konwertować wartości (np. użyć Number("2") żeby string „2” zamienić na liczbę 2).
