Строки и их методы
Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.
Строка — не просто «текст в кавычках»: у неё есть длина, индексы и десятки готовых методов. Главное правило, которое объясняет почти всё остальное: ни один метод не меняет исходную строку — все возвращают новую.
Строка в JavaScript неизменяема. Любой метод, который «меняет» текст, на самом деле собирает новое значение и отдаёт его вам, а оригинал остаётся прежним — сколько бы методов вы к нему ни применили.
Отсюда простое правило: результат вызова нужно куда-то положить — в переменную или сразу в другое выражение. Вызов ради вызова бесследно исчезает. Присвоить отдельную букву тоже не получится: city[0] = "Б" либо молча ничего не сделает, либо бросит ошибку в строгом режиме. Строку не правят — её собирают заново.
length — свойство, а не метод, скобки после него не нужны. Отдельный символ берут квадратными скобками, а at() понимает отрицательные индексы и удобно достаёт хвост строки.
Посмотрите на последнюю строку: выход за границы — не ошибка, а undefined. Молчаливый undefined потом всплывает где-нибудь в середине программы, поэтому индексы, посчитанные вручную, стоит проверять.
length считает не «символы», а единицы кодировки UTF-16. Большинство эмодзи занимают две такие единицы, поэтому счётчики длины на них ошибаются. Перебор строки через spread идёт по настоящим символам.
slice(start, end) возвращает кусок от start до end, не включая последний индекс. Отрицательные значения отсчитываются с конца — это главное удобство метода.
substring делает почти то же самое, но с двумя причудами: отрицательные аргументы он превращает в ноль, а если начало больше конца — молча меняет их местами.
| Аргументы для "javascript" | slice | substring |
|---|---|---|
| (2, 5) | vas | vas |
| (-4) | ript | javascript |
| (5, 2) | пустая строка | vas |
substring достался языку из 90-х. Пишите slice — и не придётся вспоминать, кто из них тайком переставляет аргументы.
Эти три метода отвечают на вопрос «есть ли здесь такой текст» и возвращают true или false. Регистр для них важен, поэтому перед сравнением строки обычно приводят к одному виду через toLowerCase() — так поиск перестаёт зависеть от того, как пользователь нажал Shift.
startsWith и endsWith смотрят на начало и конец — удобно проверять расширение файла или префикс. Если нужен не факт, а позиция, берите indexOf: он вернёт индекс первого совпадения или -1.
trim срезает пробелы и переводы строк по краям — первое, что делают с текстом из поля ввода. split режет строку по разделителю и отдаёт массив, join собирает массив обратно в строку. Вместе они закрывают почти всю работу со списками в тексте.
Обратите внимание: trim почистил только края всей строки, а пробелы внутри — вокруг запятых — остались, их снимаем уже у каждого элемента. Разделитель не обязан быть запятой: пробел разбивает текст на слова, а пустая строка — на отдельные символы.
replace заменяет только первое совпадение — это удивляет чаще всего остального в теме строк. Чтобы заменить все, есть replaceAll или регулярное выражение с флагом g. Регулярное выражение — это шаблон текста: в записи /три/g между косыми чертами стоит образец, а буква g после них просит найти все совпадения. Из чего ещё собирают такие шаблоны, разбирает статья «Регулярные выражения: первое знакомство».
padStart дополняет строку слева до нужной длины — классика для времени, номеров и денег. У него есть зеркальный padEnd. Если строка уже не короче заданной длины, метод просто вернёт её как есть.
В строке-замене знак доллара имеет особый смысл: $& подставляет найденный кусок, а $$ даёт один доллар. Если подставляете текст, пришедший от пользователя, помните об этой ловушке.
- Строки неизменяемы: любой метод возвращает новую строку, а оригинал остаётся прежним — результат надо сохранять.
length— свойство без скобок;s[i]иs.at(-1)дают символ, а выход за границы — тихийundefined.sliceпонимает отрицательные индексы и в большинстве случаев предпочтительнееsubstringс его перестановкой аргументов.includes,startsWith,endsWithотвечают true/false и чувствительны к регистру — снимайте его черезtoLowerCase.trim,splitиjoinпревращают текст в массив и обратно;replaceменяет только первое совпадение,padStartдополняет строку до нужной длины.
1/3let s = "кот"; s.toUpperCase(); console.log(s); — что окажется в консоли?
2/3Чему равно "javascript".slice(-6)?
3/3Что вернёт "ла-ла-ла".replace("ла", "ля")?
Обрезка длинного текста
Напишите функцию truncate(str, max): если строка длиннее max символов, вернуть первые max - 1 символов плюс многоточие …; иначе вернуть строку без изменений. Итоговая длина не должна превышать max.
Длинную строку режем через slice, короткую отдаём как есть. Многоточие занимает один символ, поэтому берём max - 1.
Сравнение именно >, а не >=: строку ровно в max символов резать незачем — она и так помещается.
Форматирование времени
Напишите formatTime(h, m), которая из чисел часов и минут делает строку вида 07:05. Числа могут быть однозначными — дополните их нулём слева.
padStart есть у строк, а не у чисел, поэтому число сначала превращаем в строку через String(). Общий кусок логики удобно вынести во вспомогательную функцию.