Var w JavaScripcie - zakres, hoisting i różnice między let i const

Grafika z napisem VAR, LET, CONST i JS. Kluczowe słowa do nauki JavaScript.

Autor

Jacek Zając

Opublikowano

8 lis 2026

Spis treści

Gdy kod JavaScript zaczyna rosnąć, słowo kluczowe var potrafi zaskoczyć bardziej niż sama składnia. Wyjaśnię, jak działa deklaracja zmiennych z użyciem var, czym różni się od let i const, a także skąd biorą się problemy z zakresem, ponowną deklaracją i hoistingiem.

Najważniejsze zasady używania var w JavaScripcie

  • var ma zakres funkcji, a nie pojedynczego bloku kodu.
  • Możesz ponownie zadeklarować zmienną i przypisać jej nową wartość.
  • Deklaracje var podlegają hoistingowi, więc przed przypisaniem wartości otrzymują undefined.
  • W nowym kodzie najczęściej lepiej wybrać const lub let.
  • var nadal pojawia się w starszych projektach, bibliotekach i kodzie wymagającym zgodności wstecznej.

Do czego służy var w JavaScripcie

var służy do deklarowania zmiennej, czyli nazwania miejsca, w którym program przechowuje wartość. Możesz od razu nadać jej wartość albo zrobić to później.

var imie = "Alicja";
var liczbaPunktow = 120;

console.log(imie);
console.log(liczbaPunktow);

W pierwszym przykładzie zmienna została jednocześnie zadeklarowana i zainicjalizowana. W drugim przypadku można rozdzielić te operacje.

var komunikat;
komunikat = "Witaj w aplikacji";

console.log(komunikat);

Zmienna utworzona za pomocą var może później otrzymać inną wartość. To odróżnia ją od const, której nie można ponownie przypisać.

var status = "oczekuje";
status = "zakończono";

console.log(status);

Sam zapis jest prosty, ale największe znaczenie ma zakres zmiennej. Właśnie tutaj zaczynają się różnice, które w większym projekcie mogą prowadzić do trudnych do znalezienia błędów.

Zakres funkcji zmienia sposób działania var

var nie respektuje zakresu blokowego. Oznacza to, że zmienna utworzona wewnątrz if, pętli albo zwykłych nawiasów klamrowych nadal jest dostępna w całej funkcji.

function sprawdzWynik() {
  if (true) {
    var wynik = 10;
  }

  console.log(wynik);
}

sprawdzWynik(); // 10

Dla osoby przyzwyczajonej do let lub const może to być nieintuicyjne. Współczesne deklaracje blokowe zatrzymują zmienną wewnątrz nawiasów klamrowych, natomiast var wychodzi poza ten blok, o ile pozostaje w tej samej funkcji.

if (true) {
  let nowaZmienna = "tekst";
  const stala = 42;
  var starszaZmienna = "widoczna";
}

console.log(starszaZmienna); // "widoczna"
console.log(nowaZmienna);    // ReferenceError
console.log(stala);         // ReferenceError

To jeden z powodów, dla których w nowych projektach częściej wybieram zakres możliwie ograniczony. Im mniej kodu ma dostęp do zmiennej, tym mniejsze ryzyko przypadkowej zmiany jej wartości.

Przeczytaj również: JS indexOf - Jak znaleźć indeks w tablicy i uniknąć pułapek?

Zakres wewnątrz funkcji

Jeżeli var pojawia się wewnątrz funkcji, zmienna jest lokalna dla tej funkcji. Kod znajdujący się poza nią nie może się do niej odwołać.

function utworzUzytkownika() {
  var rola = "administrator";
  return rola;
}

console.log(utworzUzytkownika()); // administrator
console.log(rola); // ReferenceError

Poza funkcją deklaracja var działa jako deklaracja globalna w klasycznym skrypcie przeglądarkowym. W takim przypadku może stać się właściwością obiektu globalnego, na przykład window. Moduły ES działają inaczej, dlatego top-levelowe var w module nie tworzy właściwości window.

Hoisting sprawia, że var zachowuje się nietypowo

Hoisting, czyli wyniesienie deklaracji, oznacza, że środowisko JavaScriptu przygotowuje deklarację var przed wykonaniem kodu funkcji. Nie przenosi jednak przypisanej wartości.

console.log(nazwa); // undefined

var nazwa = "Maria";

Silnik interpretuje ten fragment mniej więcej tak:

var nazwa;
console.log(nazwa); // undefined
nazwa = "Maria";

To ważne rozróżnienie. Hoisting nie sprawia, że wartość jest dostępna wcześniej. Wcześniej istnieje tylko sama zmienna, której wartość wynosi undefined.

Inaczej zachowują się let i const. Ich deklaracje również są przygotowywane, ale przed wykonaniem linii deklaracji znajdują się w tak zwanej temporal dead zone. Próba użycia zmiennej kończy się błędem ReferenceError.

console.log(nazwa); // ReferenceError

let nazwa = "Maria";

W praktyce nie traktuję hoistingu jako funkcji, z której warto korzystać. Lepiej deklarować zmienne przed ich użyciem, bo kod staje się czytelniejszy i nie wymaga od odbiorcy odtwarzania kolejności działania silnika.

Var, let i const w codziennym kodzie

Trzy słowa kluczowe służą do deklarowania zmiennych, ale różnią się zakresem, możliwością ponownego przypisania i zachowaniem przed deklaracją.

Słowo kluczowe Zakres Ponowne przypisanie Ponowna deklaracja w tym samym zakresie
var Funkcja lub globalny Tak Tak
let Blok Tak Nie
const Blok Nie Nie

W nowoczesnym JavaScripcie najczęściej zaczynam od const. Gdy wiem, że wartość będzie się zmieniać, wybieram let. var zostawiam głównie dla starszego kodu, konkretnych wymagań projektu albo sytuacji, w których trzeba zachować zgodność z istniejącą bazą kodu.

const podatek = 0.23;
let licznik = 0;

licznik += 1;

Trzeba też pamiętać, że const blokuje ponowne przypisanie zmiennej, ale nie zamraża obiektu.

const uzytkownik = {
  imie: "Olek"
};

uzytkownik.imie = "Marek"; // działa
// uzytkownik = {};        // TypeError

To częste źródło nieporozumień. Stała wskazuje na ten sam obiekt, ale właściwości tego obiektu mogą być modyfikowane, jeśli nie został dodatkowo zamrożony.

Typowe błędy związane z deklaracją var

Najbardziej podstępne problemy pojawiają się wtedy, gdy var jest używane w pętli, zwłaszcza razem z funkcjami zwrotnymi. Wszystkie funkcje mogą wtedy odwoływać się do tej samej zmiennej funkcyjnej.

for (var i = 0; i < 3; i++) {
  setTimeout(function () {
    console.log(i);
  }, 0);
}

Wynik to zazwyczaj trzy razy 3, ponieważ funkcje wykonują się po zakończeniu pętli, gdy i ma już wartość końcową. Zastosowanie let tworzy osobną wartość dla każdej iteracji.

for (let i = 0; i < 3; i++) {
  setTimeout(function () {
    console.log(i);
  }, 0);
}

Drugi problem to przypadkowa ponowna deklaracja. JavaScript nie zgłosi błędu przy takim kodzie:

var wynik = 10;
var wynik = 20;

console.log(wynik); // 20

W małym przykładzie łatwo to zauważyć. W większej aplikacji druga deklaracja może ukryć literówkę albo nadpisać wartość, którą inna część funkcji nadal uważa za aktualną. let i const wykrywają taki problem wcześniej, bo ponowna deklaracja w tym samym zakresie kończy się błędem składni.

Nie należy też mylić deklaracji z przypisaniem do niezadeklarowanej zmiennej. Taki zapis jest błędem w trybie ścisłym i może tworzyć niekontrolowane zmienne globalne w starszym kodzie.

"use strict";

liczba = 10; // ReferenceError

Kiedy używać var, a kiedy zastąpić je let lub const

Jeżeli tworzysz nowy skrypt, aplikację frontendową albo moduł JavaScriptu, rozsądnym punktem wyjścia jest const jako domyślna deklaracja. Zmień ją na let dopiero wtedy, gdy wartość rzeczywiście musi być ponownie przypisywana.

  • Wybierz const, gdy zmienna nie będzie wskazywać na inną wartość.
  • Wybierz let, gdy wartość będzie się zmieniać, na przykład w liczniku lub stanie formularza.
  • Użyj var, gdy pracujesz ze starszym kodem i zmiana mogłaby naruszyć jego działanie.
  • Przy modernizacji kodu sprawdź przede wszystkim pętle, funkcje zagnieżdżone i zmienne globalne.

Samo mechaniczne zastąpienie każdego var przez let nie zawsze jest bezpieczne. Trzeba sprawdzić, czy kod korzysta z zakresu funkcji, ponownej deklaracji albo hoistingu. W przeciwnym razie można zamienić działający, choć stary fragment na kod z błędem zakresu.

Moja praktyczna zasada jest prosta: ograniczaj zasięg zmiennej i deklaruj ją możliwie blisko miejsca użycia. Dzięki temu kod łatwiej testować, refaktoryzować i przekazywać innym osobom.

Co zapamiętać przed użyciem var w nowym projekcie

var nie jest błędem samym w sobie. To starsza, nadal poprawna część języka, która ma swoje zastosowania, ale jej zakres funkcji, hoisting i możliwość ponownej deklaracji zwiększają ryzyko pomyłek.

W nowym kodzie zwykle wybierz const, później let, a var stosuj świadomie. Jeśli rozumiesz zakres funkcji, działanie hoistingu i różnicę między przypisaniem a deklaracją, bez problemu odczytasz zarówno współczesny JavaScript, jak i starsze skrypty spotykane w projektach webowych.

FAQ - Najczęstsze pytania

var ma zakres funkcji, a nie zakres pojedynczego bloku. Dlatego zmienna zadeklarowana w if, pętli lub nawiasach klamrowych pozostaje dostępna w całej funkcji, o ile nie wykracza poza jej granice.

Silnik JavaScriptu przygotowuje deklarację var przed wykonaniem kodu, ale nie przenosi przypisanej wartości. Dlatego odwołanie przed przypisaniem zwraca undefined, a nie właściwą wartość.

Najczęściej zacznij od const, jeśli zmienna nie będzie wskazywać na inną wartość. Użyj let, gdy wartość będzie się zmieniać, a var głównie przy pracy ze starszym kodem, wymaganiami zgodności wstecznej lub istniejącą bazą kodu.

Funkcje przekazane do setTimeout wykonują się po zakończeniu pętli i odwołują się do tej samej zmiennej funkcyjnej. Po zakończeniu pętli i ma wartość 3, więc wynik to zazwyczaj trzy razy 3. Użycie let tworzy osobną wartość dla każdej iteracji.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi:

var let hoisting zakres funkcji const

Udostępnij artykuł

Jacek Zając

Jacek Zając

Nazywam się Jacek Zając i od sześciu lat zajmuję się programowaniem webowym. Moja przygoda z tym obszarem zaczęła się od chęci stworzenia własnej strony internetowej, co szybko przerodziło się w pasję do tworzenia aplikacji i rozwiązań, które mogą ułatwiać życie innym. Lubię dzielić się wiedzą, szczególnie w zakresie podstaw programowania oraz budowania responsywnych aplikacji internetowych. W moich tekstach staram się w przystępny sposób wyjaśniać złożone zagadnienia, porównując różne podejścia i technologie, a także zwracając uwagę na aktualne trendy w branży. Zawsze dbam o to, aby informacje, które przekazuję, były rzetelne i zrozumiałe, a także aby były zgodne z najnowszymi standardami. Moim celem jest nie tylko przekazywanie wiedzy, ale także inspirowanie innych do rozwijania swoich umiejętności w programowaniu.

Napisz komentarz