Switch w JavaScript bez pułapek - case, break i default

Schemat blokowy przedstawia działanie instrukcji `js switch`. Sprawdza kolejne `case`, wykonując kod, jeśli warunek jest spełniony, lub przechodzi do następnego.

Napisano przez

Jacek Zając

Opublikowano

30 wrz 2026

Spis treści

Gdy aplikacja ma zareagować inaczej na kilka konkretnych wartości, rozbudowane if...else szybko staje się mało czytelne. Instrukcja switch w JavaScript porządkuje taki kod, ale ma kilka pułapek, przede wszystkim związanych z break, porównaniem typów i przypadkowym przechodzeniem do kolejnych przypadków. Pokażę, jak działa, kiedy jej używać, czym różni się od if...else i jak pisać ją tak, żeby kod był łatwy w utrzymaniu.

Switch najlepiej sprawdza się przy wielu konkretnych wariantach jednej wartości

  • switch porównuje wyrażenie z kolejnymi etykietami case.
  • Porównanie odbywa się tak jak przy ścisłym porównaniu ===, bez automatycznej konwersji typów.
  • break zatrzymuje wykonanie i chroni przed przejściem do następnego przypadku.
  • default obsługuje wartość, dla której nie zdefiniowano osobnego case.
  • Brak break może być błędem, ale czasem świadomie wykorzystuje się go do łączenia kilku przypadków.

Schemat blokowy przedstawia działanie instrukcji switch. Sprawdza kolejne warunki (case 1, case 2, case 3), wykonując odpowiednie instrukcje lub domyślną, aż do zakończenia.

Jak działa instrukcja switch w JavaScript

switch przyjmuje jedno wyrażenie, a potem sprawdza je względem wartości zapisanych przy kolejnych case. Po znalezieniu dopasowania JavaScript uruchamia kod od tego miejsca i wykonuje go aż do napotkania break albo końca całej instrukcji.

const status = "gotowy";

switch (status) {
  case "gotowy":
    console.log("Możesz rozpocząć pracę");
    break;

  case "w trakcie":
    console.log("Operacja nadal trwa");
    break;

  case "zakończony":
    console.log("Operacja została zakończona");
    break;

  default:
    console.log("Nieznany status");
}

W tym przykładzie tylko jeden blok zostanie wykonany, ponieważ każdy przypadek kończy się instrukcją break. To najczęstszy i najbardziej przewidywalny sposób korzystania z tego mechanizmu.

Istotny szczegół polega na tym, że case nie tworzy osobnego zakresu zmiennych. Gdy deklarujesz wewnątrz przypadków zmienne za pomocą let lub const, dobrze jest użyć klamrowych bloków, szczególnie w większych instrukcjach. Dzięki temu unikasz konfliktów nazw i łatwiej kontrolujesz zakres kodu.

const typKonta = "premium";

switch (typKonta) {
  case "premium": {
    const limit = 1000;
    console.log(`Limit wynosi ${limit}`);
    break;
  }

  case "standard": {
    const limit = 100;
    console.log(`Limit wynosi ${limit}`);
    break;
  }
}

Case, break i default w praktycznych przykładach

Wartości tekstowe i liczbowe

Instrukcja może pracować z tekstami, liczbami, wartościami logicznymi, a nawet symbolami. Typ ma znaczenie, ponieważ dopasowanie jest ścisłe. Liczba 1 nie pasuje do tekstu "1".

const kod = 1;

switch (kod) {
  case "1":
    console.log("To tekst");
    break;

  case 1:
    console.log("To liczba");
    break;

  default:
    console.log("Brak dopasowania");
}

Wynik to „To liczba”. Początkujący często zakładają, że JavaScript sam zamieni typy, tak jak przy niektórych operacjach z użyciem ==. W switch takie założenie prowadzi do trudnych do zauważenia błędów, dlatego przed napisaniem przypadków sprawdzam, jaki typ naprawdę zwraca dane wyrażenie.

Domyślna reakcja

Blok default działa wtedy, gdy żaden case nie pasuje. Nie jest obowiązkowy, ale w kodzie obsługującym dane od użytkownika, adres URL albo odpowiedź serwera zwykle warto go dodać.

const metodaPlatnosci = "blik";

switch (metodaPlatnosci) {
  case "karta":
    console.log("Płatność kartą");
    break;

  case "przelew":
    console.log("Płatność przelewem");
    break;

  default:
    console.log("Wybrana metoda nie jest obsługiwana");
}

default nie powinien maskować problemu. Jeśli aplikacja dopuszcza tylko trzy wartości, a pojawia się czwarta, lepiej zalogować błąd albo pokazać jasny komunikat niż po cichu wykonać przypadkową ścieżkę.

Co się stanie bez break

Brak break powoduje tak zwany fall-through, czyli przejście do kodu kolejnego przypadku. JavaScript nie zatrzymuje się automatycznie po wykonaniu dopasowanego bloku.

const poziom = 2;

switch (poziom) {
  case 1:
    console.log("Poziom podstawowy");

  case 2:
    console.log("Poziom średni");

  case 3:
    console.log("Poziom zaawansowany");
}

Dla wartości 2 zostaną wyświetlone dwa komunikaty, dotyczące poziomu średniego i zaawansowanego. W większości przypadków to pomyłka. Świadomy fall-through ma sens wtedy, gdy kilka wartości powinno uruchomić dokładnie tę samą logikę.

const dzien = "sobota";

switch (dzien) {
  case "sobota":
  case "niedziela":
    console.log("To dzień wolny");
    break;

  default:
    console.log("To dzień roboczy");
}

Taki zapis jest czytelny, bo oba dni prowadzą do jednego wyniku. Jeżeli pominięcie break ma być celowe, dobrze zaznaczyć to komentarzem, zwłaszcza w projekcie zespołowym.

Kiedy switch jest lepszy od if...else

Najprościej przyjąć, że switch pasuje do sytuacji, w której porównujesz jedną wartość z wieloma konkretnymi możliwościami. Przykładem może być status zamówienia, typ użytkownika, nazwa widoku albo rodzaj akcji wykonanej w interfejsie.

Sytuacja Lepszy wybór Dlaczego
Jedna wartość i wiele dokładnych wariantów switch Przypadki są uporządkowane i łatwe do przeskanowania.
Zakresy, np. wynik od 0 do 49 if...else Warunki opisują relacje typu <, >= i &&.
Kilka niezależnych warunków if...else Każdy warunek może sprawdzać inną zmienną lub regułę.
Proste mapowanie nazwy na funkcję Obiekt lub mapa Dane i zachowanie można oddzielić od instrukcji sterującej.

Na przykład ocena punktowa lepiej pasuje do if...else, ponieważ sprawdza przedziały:

const punkty = 78;

if (punkty >= 90) {
  console.log("Ocena bardzo dobra");
} else if (punkty >= 70) {
  console.log("Ocena dobra");
} else if (punkty >= 50) {
  console.log("Ocena dostateczna");
} else {
  console.log("Ocena niedostateczna");
}

Z kolei wybór komunikatu na podstawie dokładnego statusu jest naturalnym zastosowaniem switch. Nie próbuję zamieniać każdego łańcucha if...else na tę instrukcję, bo przy warunkach logicznych kod często staje się wtedy mniej zrozumiały.

Praktyczne zastosowania w kodzie aplikacji

Obsługa akcji użytkownika

W aplikacji internetowej często mamy jedną nazwę akcji i kilka możliwych reakcji. Zamiast wielu porównań można uporządkować je w jednym miejscu.

function obsluzAkcje(akcja) {
  switch (akcja) {
    case "otworz":
      console.log("Otwieram panel");
      break;

    case "zapisz":
      console.log("Zapisuję dane");
      break;

    case "usun":
      console.log("Usuwam rekord");
      break;

    default:
      console.warn("Nieznana akcja");
  }
}

obsluzAkcje("zapisz");

Ten układ jest wygodny, gdy lista akcji jest zamknięta i niezbyt długa. Przy kilkunastu lub kilkudziesięciu wariantach rozważam osobne funkcje i obiekt mapujący akcje na zachowania, ponieważ jedna ogromna instrukcja zaczyna utrudniać testowanie.

Obsługa widoków i routingu

switch sprawdza się także przy prostym przełączaniu widoków na podstawie ścieżki lub identyfikatora ekranu. W prawdziwym routerze używa się zwykle gotowych mechanizmów frameworka, ale do małego projektu lub ćwiczenia taki zapis jest wystarczający.

const widok = "profil";

switch (widok) {
  case "start":
    pokazStart();
    break;

  case "profil":
    pokazProfil();
    break;

  case "ustawienia":
    pokazUstawienia();
    break;

  default:
    pokazBlad404();
}

Najważniejsza zasada brzmi tutaj normalizuj dane przed porównaniem. Jeśli wartość może zawierać wielkie litery lub przypadkowe spacje, przygotuj ją wcześniej, na przykład przez trim() i toLowerCase(). W przeciwnym razie poprawny logicznie przypadek może nie zostać rozpoznany.

Zaawansowane warianty i częste pułapki

Switch z true

Technika switch (true) pozwala sprawdzać warunki logiczne, ponieważ każdy case zwraca wartość true albo false.

const temperatura = 28;

switch (true) {
  case temperatura >= 30:
    console.log("Jest bardzo gorąco");
    break;

  case temperatura >= 20:
    console.log("Temperatura jest przyjemna");
    break;

  default:
    console.log("Jest chłodno");
}

To działa, ale nie zawsze poprawia czytelność. Przy kilku prostych przedziałach zwykłe if...else zazwyczaj mówi wprost, co się dzieje. Traktuję switch (true) jako narzędzie pomocnicze, a nie uniwersalny zamiennik warunków.

Return zamiast break

Jeśli switch znajduje się w funkcji, return może zakończyć ją wcześniej. W takim przypadku nie potrzebujesz dodatkowego break, bo funkcja przestaje wykonywać dalszy kod.

function etykietaStatusu(status) {
  switch (status) {
    case "nowy":
      return "Nowe zamówienie";

    case "wyslany":
      return "Zamówienie wysłane";

    case "anulowany":
      return "Zamówienie anulowane";

    default:
      return "Nieznany status";
  }
}

To rozwiązanie jest zwięzłe, ale używam go wtedy, gdy każdy przypadek rzeczywiście zwraca wynik. Jeśli blok wykonuje kilka operacji, zapis z break może być łatwiejszy do debugowania.

Przeczytaj również: instanceof w JavaScript - Używać czy unikać?

Obiekt jako alternatywa

Przy prostym mapowaniu wartości na tekst często wystarczy obiekt. Taki wariant usuwa powtarzające się case i bywa wygodny, gdy przypadki nie wykonują rozbudowanej logiki.

const komunikaty = {
  sukces: "Operacja zakończona powodzeniem",
  blad: "Operacja nie powiodła się",
  oczekiwanie: "Operacja jest w toku"
};

const status = "sukces";
console.log(komunikaty[status] ?? "Nieznany status");

Obiekt nie zastąpi jednak switch w każdej sytuacji. Gdy poszczególne warianty mają różne instrukcje, walidację albo kilka kroków działania, jawne przypadki nadal mogą być czytelniejsze.

Jak pisać switch bez błędów

Najwięcej problemów wynika nie z samej składni, lecz z niejasnych danych wejściowych i przypadkowego przepływu wykonania. Przed zatwierdzeniem kodu sprawdzam kilka rzeczy.

  • Czy wszystkie wartości w case mają właściwy typ?
  • Czy każdy przypadek, który nie ma celowo przechodzić dalej, kończy się break albo return?
  • Czy default obsługuje nieznane i niepoprawne dane?
  • Czy warunki nie dotyczą zakresów, dla których lepsze będzie if...else?
  • Czy nazwy przypadków są spójne z wartościami zwracanymi przez API lub formularz?

Dobrym zwyczajem jest także włączenie reguły no-fallthrough w ESLint. Narzędzie ostrzeże o przypadkach, w których kod przechodzi do kolejnej etykiety bez wyraźnego zakończenia. Nie zastąpi testów, ale szybko wyłapuje jedną z najbardziej typowych pomyłek.

Nie komplikowałbym też instrukcji dodatkowymi zagnieżdżeniami. Jeżeli pojedynczy case ma kilkadziesiąt linii, wydziel jego logikę do osobnej funkcji. Dzięki temu sam switch pozostaje krótką mapą decyzji, a szczegóły działania są testowalne osobno.

Mała decyzja, która robi dużą różnicę w czytelności kodu

Instrukcja switch jest dobrym wyborem dla wielu dokładnych wariantów jednej wartości. Zapamiętaj trzy elementy: porównanie jest ścisłe, break zatrzymuje dalsze wykonanie, a default zabezpiecza kod przed nieobsłużonym przypadkiem.

W praktyce najbardziej opłaca się używać jej oszczędnie i świadomie. Gdy potrzebujesz zakresów, złożonych warunków albo niezależnych reguł, wybierz if...else; gdy mapujesz proste klucze na dane, rozważ obiekt. Taki dobór narzędzia sprawia, że kod JavaScript pozostaje przewidywalny także wtedy, gdy aplikacja zaczyna rosnąć.

FAQ - Najczęstsze pytania

switch sprawdza się, gdy porównujesz jedną wartość z wieloma konkretnymi wariantami, na przykład statusem lub typem akcji. Przy zakresach, takich jak przedziały punktów, oraz kilku niezależnych warunkach lepsze będzie if...else. Proste mapowanie nazwy na tekst można natomiast zastąpić obiektem.

Po znalezieniu dopasowania JavaScript wykonuje kod od tego miejsca aż do napotkania break albo końca instrukcji. Brak break powoduje fall-through, czyli przejście do następnych przypadków. Można użyć tego celowo, aby kilka wartości uruchamiało tę samą logikę, na przykład sobota i niedziela.

Nie. Dopasowanie działa tak jak ścisłe porównanie ===, dlatego liczba 1 nie pasuje do tekstu "1". Przed napisaniem przypadków warto sprawdzić, jaki typ rzeczywiście zwraca wyrażenie.

Dodaj blok default, aby obsłużyć wartości bez osobnego case i wyświetlić jasny komunikat albo zalogować błąd. Dane wejściowe można wcześniej normalizować przez trim() i toLowerCase(). Reguła no-fallthrough w ESLint pomaga wykrywać przypadkowe pomijanie break.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi:

switch break default fall-through eslint

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