Строки и регулярные выражения
Строка в JavaScript — это неизменяемый примитив: ни один метод не меняет её на месте, все они возвращают новую строку. Второй ключевой факт — строка хранится в UTF-16, поэтому .length считает код-юниты, а не воспринимаемые символы, и эмодзи «весит» два. Кто держит в голове эти два свойства, не пишет багов с «изменением» строки и подсчётом длины.
Поверх строк язык даёт шаблонные литералы с интерполяцией и их продвинутую форму — теговые шаблоны, а для сложного поиска — регулярные выражения с флагами и двумя семействами методов. Регулярки прячут собственную ловушку — состояние lastIndex у флага g. Полная карта — в слоях ниже.
Карта темы
- Основы строк — неизменяемость примитива и UTF-16 — код-юниты, код-поинты, суррогатные пары.
- Методы строк —
slice,substring,indexOf,toUpperCase,trimи их отличия. - Поиск в строке —
includes,startsWith,endsWith,indexOfи когда какой уместен. - Сравнение строк —
===и<по код-юнитам противlocaleCompare. - Шаблонные литералы — бэктики, интерполяция
${...}и многострочность. - Теговые шаблоны — функция-тег, массив кусков, значения и
.raw. - Основы регулярок — литерал
/x/противnew RegExp, группы, жадность. - Методы регулярок —
test/execна регулярке противmatch/matchAll/replace/searchна строке. - Флаги регулярок —
g,i,m,s,u,yи состояниеlastIndex.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
| Ждать, что метод строки изменит её на месте | Строка неизменяема — метод возвращает новую, оригинал цел |
Считать .length числом символов | .length считает код-юниты UTF-16 — эмодзи даёт 2 |
Путать slice и substring на отрицательных индексах | slice считает с конца, substring обнуляет отрицательные |
Сравнивать строки на равенство через </> для порядка человека | Порядок по код-юнитам — заглавные раньше строчных; нужен localeCompare |
Переиспользовать один /g/-regex в цикле | lastIndex копит состояние — часть совпадений пропускается |
Думать, что квантификаторы +/* ленивы | Они жадны — берут максимум; ленивость даёт +?/*? |
Путать test/exec (на регулярке) и match (на строке) | Разный получатель и разный тип результата |
Значение для собеседований
Строки и регулярки спрашивают как проверку внимательности к деталям — понимаете ли вы неизменяемость, кодировку и состояние g-регулярки. Кандидат, который на «сколько символов в строке с эмодзи» отвечает «.length даст код-юниты, а по код-поинтам считает [...str].length», выделяется сразу.
Что обычно проверяют:
- Изменяема ли строка и что происходит при
str[0] = 'x'. - Что считает
.lengthи как перебрать строку по код-поинтам. - Чем
sliceотличается отsubstring, аincludesотindexOf. - Почему общий
/g/-regex в цикле пропускает совпадения и что такоеlastIndex.
Типичный неверный ответ: «str.replace('a', 'b') изменит строку». Нет — строка неизменяема, replace возвращает новую строку, а исходная переменная не поменяется без переприсваивания.