Napisy i szablony tekstowe
Tekst to najczęściej przetwarzany rodzaj danych w aplikacjach webowych. Poznajesz kilkanaście metod, które robią z nim wszystko: przycinają, szukają, podmieniają i formatują — a na koniec budujesz generator szkolnych adresów e-mail.
Czego się dziś nauczysz
- Zbudujesz komunikat szablonem w backtickach zamiast sklejania plusami
- Wybierzesz właściwą metodę do wyszukiwania, wycinania i podmiany fragmentu tekstu
- Sformatujesz tabelkę w konsoli, wyrównując kolumny
- Wyjaśnisz, dlaczego
tekst.toUpperCase()nie zmienia zmiennejtekst - Napiszesz program zamieniający dane osobowe na login i adres e-mail
Szablony tekstowe
Sklejanie plusami działa, ale przy dłuższych komunikatach robi się nieczytelne — łatwo zgubić spację albo cudzysłów. Szablon w backtickach rozwiązuje oba problemy:
const imie = "Marta";
const klasa = "3TI";
const punkty = 37;
const maks = 40;
// sklejanie plusami — czytelne tylko przy dwóch elementach
console.log("Uczennica " + imie + " z klasy " + klasa + " ma " + punkty + "/" + maks + " pkt");
// szablon — to samo, ale widać strukturę zdania
console.log(`Uczennica ${imie} z klasy ${klasa} ma ${punkty}/${maks} pkt`);
W nawiasach ${…} może stanąć dowolne wyrażenie — nie tylko nazwa zmiennej:
const punkty = 37;
const maks = 40;
console.log(`Wynik: ${((punkty / maks) * 100).toFixed(1)}%`);
console.log(`Status: ${punkty >= 20 ? "zdany" : "niezdany"}`);
console.log(`Do maksimum brakuje ${maks - punkty} pkt`);
Tekst wielolinijkowy
Szablon zachowuje wszystkie złamania wierszy zapisane w kodzie — nie trzeba już
\n ani sklejania:
const uczen = "Marta Kowalska";
const srednia = 4.36;
const swiadectwo = `
╔════════════════════════════════════╗
║ ŚWIADECTWO ŚRÓDROCZNE
║ Uczeń: ${uczen}
║ Średnia: ${srednia.toFixed(2)}
║ Wynik: ${srednia >= 4.75 ? "z wyróżnieniem" : "promocja"}
╚════════════════════════════════════╝
`;
console.log(swiadectwo);
Backtick na klawiaturze
Znak ` znajdziesz na klawiszu obok lewego Shifta (na układzie polskim programisty)
lub pod Escape. To nie jest apostrof ' — apostrof nie uruchomi podstawiania
${…}.
Znaki specjalne
| Zapis | Znaczenie | Przykład |
|---|---|---|
\n | nowa linia | "Linia 1\nLinia 2" |
\t | tabulator | "Imię\tOcena" |
\" | cudzysłów wewnątrz tekstu | "Powiedział \"cześć\"" |
\\ | ukośnik wsteczny | "C:\\Users\\uczen" |
\` | backtick w szablonie | `znak \` w tekście` |
console.log("Imię\tOcena\n----\t-----\nAla\t5\nBartek\t4");
console.log("Ścieżka: C:\\Program Files\\Node");
console.log('Uczeń powiedział: "to działa!"'); // apostrofy pozwalają uniknąć ukośników
Imię Ocena
---- -----
Ala 5
Bartek 4
Ścieżka: C:\Program Files\Node
Uczeń powiedział: "to działa!"
Metody tekstu, których naprawdę używasz
Podstawowe informacje
const tekst = " Programowanie w TypeScript ";
console.log(tekst.length); // 30 — razem ze spacjami
console.log(tekst.trim()); // "Programowanie w TypeScript"
console.log(tekst.trim().length); // 26
console.log(tekst.toUpperCase()); // WIELKIMI LITERAMI
console.log(tekst.toLowerCase()); // małymi literami
Szukanie
const mail = "marta.kowalska@zsmi.edu.pl";
console.log(mail.includes("@")); // true — czy zawiera
console.log(mail.startsWith("marta")); // true — czy zaczyna się od
console.log(mail.endsWith(".pl")); // true — czy kończy się na
console.log(mail.indexOf("@")); // 14 — na której pozycji
console.log(mail.indexOf("xyz")); // -1 — nie znaleziono
Numerowanie zaczyna się od zera
Pierwszy znak tekstu ma numer 0, ostatni ma numer length - 1.
Metoda indexOf zwraca -1, gdy niczego nie znajdzie — dlatego typowy
warunek to if (mail.indexOf("@") !== -1), choć czytelniejsze jest po prostu
if (mail.includes("@")).
Wycinanie fragmentów
const pesel = "04231512345";
console.log(pesel.slice(0, 2)); // "04" — rok
console.log(pesel.slice(2, 4)); // "23" — miesiąc (z zakodowanym stuleciem)
console.log(pesel.slice(4, 6)); // "15" — dzień
console.log(pesel.slice(-1)); // "5" — ostatni znak
console.log(pesel.charAt(0)); // "0" — pojedynczy znak
console.log(pesel[0]); // "0" — to samo, krócej
W slice(od, do) pierwszy numer jest brany, a drugi już nie — wycinamy „do, ale bez”.
Dzięki temu slice(0, 2) daje dokładnie dwa znaki.
Zmiana treści
const zdanie = "kot ma ala, ala ma kota";
console.log(zdanie.replace("ala", "Ola")); // tylko pierwsze wystąpienie
console.log(zdanie.replaceAll("ala", "Ola")); // wszystkie wystąpienia
console.log("ab".repeat(3)); // "ababab"
console.log("7".padStart(3, "0")); // "007" — wiodące zera
console.log("Ala".padEnd(10, ".") + "|"); // "Ala.......|" — wyrównanie kolumn
Ściąga
| Metoda | Do czego |
|---|---|
.length | liczba jednostek UTF-16; dla zwykłych liter często odpowiada liczbie znaków. Właściwość, bez nawiasów. |
.trim() | Usuwa białe znaki z początku i końca. Używaj, gdy otaczające spacje nie są częścią danych; nie przycinaj automatycznie np. haseł. |
.toUpperCase() / .toLowerCase() | zmiana wielkości liter, także przed porównaniem |
.includes(x) | czy tekst zawiera fragment |
.startsWith(x) / .endsWith(x) | sprawdzenie początku lub końca |
.indexOf(x) | pozycja fragmentu albo -1 |
.slice(od, do) | wycięcie fragmentu; liczby ujemne liczą od końca |
.replace(a, b) / .replaceAll(a, b) | podmiana pierwszego / wszystkich wystąpień |
.split(x) | rozbicie tekstu na tablicę (lekcja 08) |
.padStart(n, z) / .padEnd(n, z) | dopełnienie do zadanej długości |
.repeat(n) | powtórzenie tekstu — świetne do rysowania linii |
Tekstu nie da się zmienić
To najczęstsze potknięcie na tym etapie. Żadna metoda tekstu nie modyfikuje oryginału — każda zwraca nowy tekst:
let nazwa = " ala ";
nazwa.trim(); // wynik wyrzucony do kosza!
console.log(`[${nazwa}]`); // [ ala ] — bez zmian
nazwa = nazwa.trim(); // tak jest dobrze
console.log(`[${nazwa}]`); // [ala]
// metody można łączyć w łańcuch — każda działa na wyniku poprzedniej
const login = " Marta Kowalska ".trim().toLowerCase().replace(" ", ".");
console.log(login); // marta.kowalska
Nie da się też podmienić pojedynczego znaku
nazwa[0] = "A"; nie zgłosi błędu w JavaScripcie, ale też nic nie zrobi.
Żeby zmienić pierwszą literę, buduje się nowy tekst:
nazwa = nazwa[0].toUpperCase() + nazwa.slice(1);
Generator kont szkolnych
Administrator dostaje listę uczniów i musi utworzyć im konta. Program zamienia dane osobowe na login, adres e-mail i hasło startowe według ustalonych reguł.
// ── dane wejściowe, tak jak przychodzą z arkusza ──
const imieSurowe = " Łukasz ";
const nazwiskoSurowe = "Wiśniewski-Nowak ";
const klasa = "3ti";
const numerWDzienniku = 7;
const DOMENA = "zsmi.edu.pl";
// ── 1. Porządkowanie danych ──
const imie = imieSurowe.trim();
const nazwisko = nazwiskoSurowe.trim();
// ── 2. Usunięcie polskich znaków ──
const bezOgonkow = (nazwisko + "." + imie)
.toLowerCase()
.replaceAll("ą", "a").replaceAll("ć", "c").replaceAll("ę", "e")
.replaceAll("ł", "l").replaceAll("ń", "n").replaceAll("ó", "o")
.replaceAll("ś", "s").replaceAll("ź", "z").replaceAll("ż", "z");
// ── 3. Usunięcie znaków niedozwolonych w loginie ──
const login = bezOgonkow.replaceAll("-", "").replaceAll(" ", "");
// ── 4. Adres e-mail i hasło startowe ──
const email = `${login}@${DOMENA}`;
const numerZZerem = String(numerWDzienniku).padStart(2, "0");
const haslo = `${klasa.toUpperCase()}-${imie.slice(0, 1).toUpperCase()}${nazwisko.slice(0, 3).toLowerCase()}-${numerZZerem}`;
// ── 5. Raport ──
console.log("─".repeat(46));
console.log("Uczeń:".padEnd(10) + `${imie} ${nazwisko}`);
console.log("Klasa:".padEnd(10) + klasa.toUpperCase());
console.log("Login:".padEnd(10) + login);
console.log("E-mail:".padEnd(10) + email);
console.log("Hasło:".padEnd(10) + haslo);
console.log("─".repeat(46));
console.log(`Długość loginu: ${login.length} znaków`);
──────────────────────────────────────────────
Uczeń: Łukasz Wiśniewski-Nowak
Klasa: 3TI
Login: wisniewskinowak.lukasz
E-mail: wisniewskinowak.lukasz@zsmi.edu.pl
Hasło: 3TI-Łwiś-07
──────────────────────────────────────────────
Długość loginu: 22 znaków
Omówienie krok po kroku
| Fragment | Po co |
|---|---|
.trim() na wejściu |
Dane kopiowane z arkuszy niemal zawsze mają zbędne spacje. Bez tego login zacząłby się od spacji i konto byłoby nie do użycia. |
łańcuch .replaceAll(…) |
Adresy e-mail nie powinny zawierać polskich znaków. Każde wywołanie działa na wyniku poprzedniego — to bezpośrednia konsekwencja niezmienności tekstu. |
String(numer).padStart(2, "0") |
Numer 7 staje się "07". Najpierw zamiana liczby na tekst, bo padStart
jest metodą tekstu, nie liczby. |
nazwisko.slice(0, 3) |
Trzy pierwsze litery nazwiska do hasła startowego. Zwróć uwagę: znaki polskie tu zostają, bo hasło nie musi ich unikać. |
"Uczeń:".padEnd(10) |
Wyrównanie kolumn w konsoli. Prostszy i pewniejszy sposób niż liczenie tabulatorów. |
"─".repeat(46) |
Linia oddzielająca. Zamiast wklejać 46 znaków, mówimy programowi, żeby je powtórzył. |
Jak zrobiłby to zawodowiec
Dziewięć wywołań replaceAll to sporo powtórzeń. W prawdziwym projekcie użyłoby się
jednego wyrażenia regularnego albo metody normalize("NFD"). Tutaj wersja „ręczna” jest
czytelniejsza — a do funkcji, które pozwolą to porządnie opakować, dojdziemy w lekcji 11.
Na co uważać
| Kod | Problem |
|---|---|
tekst.length() | length to właściwość, nie metoda — bez nawiasów. |
tekst.trim(); bez przypisania | Wynik przepada. Musi być tekst = tekst.trim(); |
'Cześć ${imie}' | Podstawianie działa tylko w backtickach, nie w apostrofach. |
tekst.slice(1, 3) gdy chcesz 3 znaki | Dostaniesz dwa. Drugi numer to pozycja, przed którą kończymy. |
"Ala" === "ala" | Fałsz. Przed porównaniem sprowadź obie strony do jednej wielkości liter. |
"5" + 3 | Sklejanie, nie dodawanie. Najpierw Number("5"). |
Warunki w przykładach
Fragmenty z if służą tu wyłącznie pokazaniu, jak używa się wyniku indexOf albo includes. Samą instrukcję warunkową omawiamy w lekcji 06 — żadne zadanie z tej lekcji nie wymaga jej napisania.
Zadania
const s = "TypeScript";
console.log(s.length);
console.log(s.slice(0, 4));
console.log(s.slice(-6));
console.log(s.toUpperCase().includes("SCRIPT"));
console.log(s.indexOf("z"));
console.log("=".repeat(5));
pokaż rozwiązanie
10
Type
Script
true
-1 małe "z" nie występuje — jest wielkie "S"... i małe "cript"
=====
Przepisz swoją wizytówkę z lekcji 2, zastępując wszystkie sklejania plusami jednym szablonem wielolinijkowym w backtickach. Dodaj linię obliczeniową, na przykład liczbę lat do matury.
Sprawdź uproszczone reguły poprawności adresu zapisanego w zmiennej: zawiera dokładnie jeden znak
@, ma co najmniej 5 znaków, nie zaczyna się i nie kończy kropką, a po znaku @
występuje kropka. Wypisz wynik każdego sprawdzenia osobno oraz ocenę końcową.
pokaż wskazówki i rozwiązanie
const email = "marta.kowalska@zsmi.edu.pl";
const poz = email.indexOf("@");
const jedenMalpa = poz !== -1 && email.indexOf("@", poz + 1) === -1;
const dlugoscOk = email.length >= 5;
const kropkiOk = !email.startsWith(".") && !email.endsWith(".");
const domenaOk = poz !== -1 && email.slice(poz).includes(".");
console.log(`jeden @: ${jedenMalpa}`);
console.log(`długość: ${dlugoscOk}`);
console.log(`kropki: ${kropkiOk}`);
console.log(`domena: ${domenaOk}`);
console.log(`ADRES ${jedenMalpa && dlugoscOk && kropkiOk && domenaOk ? "POPRAWNY" : "BŁĘDNY"}`);
indexOf przyjmuje drugi argument — pozycję, od której zacząć szukanie.
Dzięki temu sprawdzamy, czy za pierwszą małpą jest jeszcze jedna.
Napisz program, który ukrywa część danych, tak jak robią to systemy bankowe:
- numer telefonu
"501234567"→"501***567" - adres
"marta.kowalska@zsmi.edu.pl"→"ma***********@zsmi.edu.pl" - numer karty
"4532015112830366"→"**** **** **** 0366"
Nie wpisuj gwiazdek ręcznie — policz, ile ich potrzeba, i użyj repeat.
pokaż rozwiązanie
const tel = "501234567";
const maskaTel = tel.slice(0, 3) + "*".repeat(tel.length - 6) + tel.slice(-3);
console.log(maskaTel);
const mail = "marta.kowalska@zsmi.edu.pl";
const poz = mail.indexOf("@");
const maskaMail = mail.slice(0, 2) + "*".repeat(poz - 2) + mail.slice(poz);
console.log(maskaMail);
const karta = "4532015112830366";
console.log(`**** **** **** ${karta.slice(-4)}`);
Mając numer PESEL w zmiennej tekstowej, wyłuskaj i wypisz: rok, miesiąc i dzień urodzenia oraz płeć (przedostatnia cyfra: parzysta oznacza kobietę, nieparzysta mężczyznę). Sprawdź też, czy numer ma dokładnie 11 znaków. Załóż na razie, że osoba urodziła się w latach 1900–1999 (miesiąc bez dodatku stulecia).
pokaż rozwiązanie
const pesel = "94051812345";
const dlugoscOk = pesel.length === 11;
const rok = 1900 + Number(pesel.slice(0, 2));
const miesiac = pesel.slice(2, 4);
const dzien = pesel.slice(4, 6);
const cyfraPlci = Number(pesel[9]);
const plec = cyfraPlci % 2 === 0 ? "kobieta" : "mężczyzna";
console.log(`Poprawna długość: ${dlugoscOk}`);
console.log(`Data urodzenia: ${dzien}.${miesiac}.${rok}`);
console.log(`Płeć: ${plec}`);
Zwróć uwagę, że dzień i miesiąc zostawiamy jako tekst — chcemy zachować wiodące zera
("05", a nie 5). Rok musi być liczbą, bo dodajemy do niego 1900.
Wybór między tekstem a liczbą zależy od tego, co zamierzasz z daną zrobić.
Granice przykładów
"😀".length daje 2, bo length liczy jednostki UTF-16. charAt poza zakresem daje pusty tekst, a indeksowanie tekst[i] daje undefined. Reguły hasła, adresu e-mail i wycinanie PESEL w zadaniach są uproszczeniami do nauki metod tekstu: generator nie tworzy bezpiecznego hasła, a wycinanie daty nie sprawdza całego numeru ani sumy kontrolnej.
Co trzeba zapamiętać
- Szablon w backtickach z
${…}zastępuje sklejanie plusami i obsługuje wiele linii. - Żadna metoda nie zmienia oryginalnego tekstu — zawsze przypisuj wynik.
- Metody można łączyć w łańcuch:
tekst.trim().toLowerCase().replace(…) - Znaki numeruje się od zera;
slice(od, do)nie bierze znaku spod numerudo. - Przycinaj otaczające białe znaki tylko tam, gdzie zgadza się to z regułą danych.
padStart,padEndirepeatrobią porządek w wypisywanych raportach.