Metoda substring() w JavaScript służy do wycinania fragmentu tekstu i przydaje się częściej, niż wygląda to na pierwszy rzut oka. W praktyce temat, który często kryje się pod hasłem js substring, sprowadza się do jednej rzeczy: bezpiecznego pobierania kawałka stringa bez niepotrzebnych niespodzianek. Pokażę, jak działają indeksy, co zwraca metoda w różnych sytuacjach, czym różni się od slice() i jak unikać błędów, które początkujący powtarzają najczęściej.
Najważniejsze zasady w jednym miejscu
-
substring()zwraca nowy string i nie modyfikuje oryginału. - Pierwszy argument oznacza indeks startowy, a drugi - indeks końcowy bez tego znaku.
- Gdy drugi argument pominiesz, metoda pobierze tekst aż do końca.
- Jeśli
startjest większy odend, JavaScript zamieni je miejscami. - Wartości ujemne i
NaNsą traktowane jak0. -
slice()bywa wygodniejsze przy indeksach ujemnych, asubstr()lepiej omijać.
Czym jest substring i kiedy się przydaje
substring() to metoda do wycinania części tekstu po indeksach. Najczęściej używam jej wtedy, gdy format danych jest przewidywalny: kod produktu, data w formacie YYYY-MM-DD, fragment adresu e-mail, numer zamówienia albo nazwa pliku z rozszerzeniem. To dobre narzędzie, gdy wiesz od którego znaku i do którego znaku chcesz pobrać tekst.
Ważna rzecz: metoda zwraca nowy string. Oryginalny napis zostaje bez zmian, więc możesz bezpiecznie używać go dalej w kodzie. To praktyczne przy walidacji formularzy, parsowaniu danych i prostych transformacjach tekstu, gdzie nie potrzebujesz regexów ani dzielenia całego stringa na tablicę. Zanim przejdziemy do reguł indeksowania, zobaczmy dokładnie, co dzieje się pod maską.
Jak liczone są indeksy i co zwraca metoda
JavaScript liczy pozycje znaków od zera, więc pierwszy znak ma indeks 0, drugi 1, trzeci 2 i tak dalej. Drugi argument substring() działa jak granica wyłączenia: znak spod tego indeksu nie trafia do wyniku. To właśnie ten detal najczęściej myli osoby, które dopiero zaczynają pracę z tekstem.
const text = "Mozilla";
console.log(text.substring(1, 3)); // "oz"
console.log(text.substring(2)); // "zilla"
console.log(text.substring(4, 4)); // ""
W praktyce oznacza to, że substring(1, 3) zwróci znaki z pozycji 1 i 2, ale już nie 3. Jeśli drugi argument pominiesz, metoda pobierze wszystko od wskazanego miejsca do końca napisu. Jeśli oba indeksy są takie same, wynik będzie pustym stringiem. Taki sposób działania jest prosty, ale wymaga dokładności przy liczeniu pozycji, dlatego warto znać kilka reguł brzegowych.
| Wywołanie | Wynik | Co to oznacza |
|---|---|---|
"Mozilla".substring(1, 3) |
"oz" |
Pobiera znaki od indeksu 1 do 2. |
"Mozilla".substring(4) |
"lla" |
Gdy nie podasz końca, metoda idzie do końca tekstu. |
"Mozilla".substring(4, 4) |
"" |
Ten sam początek i koniec daje pusty wynik. |
"Mozilla".substring(5, 2) |
"zil" |
Jeśli start jest większy od końca, argumenty zostaną zamienione miejscami. |
Kiedy te zasady są już jasne, można przejść do szczegółów, które naprawdę robią różnicę w codziennym kodzie: wartości ujemnych, zakresu długości i znaków spoza podstawowego alfabetu.
Najważniejsze reguły, które ratują przed błędami
Największą zaletą substring() jest przewidywalność, ale tylko wtedy, gdy pamiętasz o kilku ograniczeniach. W praktyce warto zapamiętać cztery rzeczy: argumenty są liczone od zera, końcowy indeks jest wyłączny, wartości poza zakresem są przycinane do dozwolonego przedziału, a start większy od końca nie powoduje błędu, tylko zamianę miejscami.
-
Wartości ujemne nie działają jak „liczenie od końca”. W
substring()są traktowane jak0, więcsubstring(-5, 2)nie oznacza „od piątego znaku od końca”. -
NaNtakże zamienia się w0. To przydatne przy danych wejściowych, które nie zawsze są czyste, ale nie zastępuje walidacji. - Indeksy większe niż długość tekstu są przycinane. Jeśli podasz zbyt duży zakres, JavaScript nie wywali błędu, tylko zakończy na końcu stringa.
- Oryginalny napis zostaje nietknięty. Metoda tylko zwraca fragment, więc nie musisz obawiać się skutków ubocznych.
- Znaki wizualne nie zawsze są jednym indeksem. Przy emoji i niektórych znakach złożonych string może zachowywać się inaczej, bo JavaScript operuje na jednostkach UTF-16, a nie na „ludzkich” znakach widocznych na ekranie.
Ta ostatnia rzecz jest ważniejsza, niż się wydaje. Jeśli pracujesz z nazwami użytkowników, emoji albo tekstem tworzonym przez ludzi, a nie maszynę, warto uważać, bo prosty wycinek może przeciąć znak w pół. Z tego powodu do bardziej złożonego tekstu często lepiej nadaje się segmentacja albo wycinanie po separatorach, a nie ślepe indeksy.
Skoro reguły są już jasne, zobaczmy, jak przełożyć je na realne zadania, z którymi spotyka się każdy frontendowiec i backendowiec.
Praktyczne przykłady z codziennego kodu
W codziennej pracy najczęściej wycinam fragment tekstu nie po to, żeby „pokazać metodę”, tylko żeby rozwiązać konkretny problem. Poniższe przykłady są proste, ale dobrze pokazują, gdzie substring() naprawdę oszczędza czas.
// 1. Pobranie prefiksu z kodu zamówienia
const orderCode = "INV-2026-048";
const prefix = orderCode.substring(0, 3);
console.log(prefix); // "INV"Ten przypadek jest dobry, gdy format jest stały. Nie musisz analizować całego stringa, bo interesuje cię tylko pierwszy segment.
// 2. Ostatnie 4 znaki numeru
const accountNumber = "1234567812345678";
const last4 = accountNumber.substring(accountNumber.length - 4);
console.log(last4); // "5678"To wygodny sposób, gdy chcesz zamaskować numer i zostawić tylko końcówkę. Ja często używam takiego podejścia przy podglądzie danych w panelach administracyjnych.
// 3. Rozszerzenie pliku
const fileName = "report.final.pdf";
const dotIndex = fileName.lastIndexOf(".");
const extension = dotIndex === -1 ? "" : fileName.substring(dotIndex + 1);
console.log(extension); // "pdf"Ten przykład pokazuje coś ważnego: substring() bardzo dobrze współpracuje z lastIndexOf(). Najpierw szukasz separatora, potem wycinasz interesujący fragment. To zwykle czytelniejsze niż budowanie skomplikowanego wyrażenia regularnego.
// 4. Rok z daty w formacie YYYY-MM-DD
const date = "2026-06-29";
const year = date.substring(0, 4);
console.log(year); // "2026"Przy danych o sztywnej strukturze to rozwiązanie jest szybkie i wystarczająco odporne, o ile wcześniej walidujesz format. Jeśli jednak separator może się zmieniać, lepiej najpierw sprawdzić strukturę wejścia. Następny krok to porównanie z innymi metodami, bo właśnie tu pojawia się najwięcej nieporozumień.
Substring, slice i substr w praktyce
Te trzy metody są podobne tylko na pierwszy rzut oka. W realnym kodzie różnica między nimi bywa bardzo konkretna, szczególnie gdy pracujesz z indeksami ujemnymi albo musisz utrzymać starszy projekt.
| Metoda | Jak działa zakres | Ujemne indeksy | Status | Kiedy wybrać |
|---|---|---|---|---|
substring() |
start do end, bez znaku końcowego |
Traktowane jak 0
|
Standardowa | Gdy chcesz prostego wycinania po pozycjach i nie potrzebujesz liczenia od końca. |
slice() |
start do end, bez znaku końcowego |
Liczone od końca stringa | Standardowa | Gdy chcesz wygodnie ucinać fragmenty od końca albo pracować na ujemnych indeksach. |
substr() |
start + liczba znaków |
Obsługa zależna od startu, ale metoda jest legacy | Nie zalecana | Tylko przy starym kodzie, który jeszcze tego używa. W nowych projektach lepiej unikać. |
Jeśli mam wybrać jedną metodę do prostych, indeksowych wycięć, zwykle wybieram substring(). Gdy potrzebuję logicznie odcinać końcówkę albo pracuję od końca tekstu, częściej sięgam po slice(). substr() zostawiam w spokoju, bo to rozwiązanie starego typu, które dziś tylko komplikuje kod. Z tego właśnie wynikają najczęstsze błędy, o których warto powiedzieć wprost.
Typowe błędy i bezpieczne nawyki
Najwięcej problemów nie bierze się z samej metody, tylko z błędnego założenia, że działa „intuicyjnie”. Nie działa. Działa konsekwentnie, ale trzeba znać jej reguły.
-
Mylenie końca z zakresem zamkniętym. Jeśli chcesz pobrać znaki od 0 do 3, musisz podać
substring(0, 4), bo indeks końcowy jest wyłączny. -
Zakładanie, że ujemne indeksy liczą od końca. To zachowanie kojarzy się ze
slice(), nie zsubstring(). -
Bezrefleksyjne używanie zamiany argumentów. To, że
substring(8, 3)„zadziała”, nie znaczy jeszcze, że kod jest czytelny. Czasem lepiej jawnie uporządkować indeksy. - Cięcie tekstu złożonego z emoji lub znaków wielokodowych. Jeśli liczy się widoczny znak, a nie jednostka kodowa, prosty substring może dać zaskakujący efekt.
-
Wchodzenie w
substr()ze starego odruchu. Nowy kod powinien opierać się nasubstring()alboslice(), bo są standardowe i przewidywalne.
Najbezpieczniejszy nawyk, jaki wyrobiłem sobie w praktyce, jest prosty: zanim napiszę wycinek, pytam sam siebie, czy pracuję na stałym formacie, czy na tekście od użytkownika. Jeśli format jest stabilny, substring() jest bardzo wygodne. Jeśli dane są luźne i zależą od separatorów, zwykle lepiej najpierw znaleźć granicę tekstu, a dopiero potem go wyciąć. To prowadzi do ostatniej kwestii: kiedy ta metoda naprawdę ma sens, a kiedy tylko udaje rozwiązanie.
Kiedy substring oszczędza czas, a kiedy lepiej sięgnąć po inną metodę
substring() najlepiej działa wtedy, gdy masz kontrolę nad formatem danych. W panelach administracyjnych, przy kodach zamówień, numerach wersji, datach, identyfikatorach i stałych prefiksach jest szybkie, czytelne i mało podatne na błędy. Właśnie dlatego tak często pojawia się w prawdziwych projektach, a nie tylko w ćwiczeniach.
Jeśli jednak tekst jest nieprzewidywalny, lepiej nie udawać, że kilka indeksów załatwi sprawę. Gdy chcesz pobrać część przed separatorem, część po nim albo fragment zależny od wzorca, często lepszy będzie duet indexOf() + slice(), ewentualnie regex. Z mojej perspektywy to nie jest kwestia „które narzędzie jest lepsze”, tylko które najczytelniej opisuje problem.
Najkrócej: substring() wybieraj wtedy, gdy myślisz w granicach indeksów, a nie w kategoriach wyszukiwania wzorców. Przy prostych, stałych strukturach tekstu to jedna z najbardziej praktycznych metod w JavaScript, bo robi dokładnie to, czego od niej oczekujesz, bez zbędnej otoczki.