JS строки
Строка в JavaScript — неизменяемая (immutable) последовательность символов Unicode, примитивный тип данных с богатым встроенным API для обработки текста.
Зачем нужно
Строки — один из наиболее часто используемых типов данных: имена, адреса, URL, шаблоны HTML, JSON. Понимание методов строк позволяет без лишнего кода реализовывать поиск, форматирование, валидацию и трансформацию текста. Template literals (шаблонные строки) ES6 упрощают интерполяцию и многострочный текст.
Где используется
- Форматирование данных для отображения: имена, даты, суммы
- Работа с URL: парсинг, построение query-параметров
- Шаблоны: генерация HTML, SQL-запросов (через параметры), сообщений
- Валидация: проверка email, телефона, длины пароля
- Парсинг: split по разделителю, извлечение подстрок
Основной контент
Создание и базовые свойства
const s1 = 'одинарные кавычки';
const s2 = "двойные кавычки";
const name = 'Иван';
const s3 = `шаблонная строка: ${name}`; // Template literal
// Длина
console.log('hello'.length); // 5
// Доступ к символу
console.log('hello'[0]); // 'h'
console.log('hello'.at(-1)); // 'o' (с конца, ES2022)
console.log('hello'.charAt(1)); // 'e'
// Строки неизменяемы — все методы возвращают новую строку
let str = 'Hello';
str[0] = 'J'; // тихо игнорируется
console.log(str); // 'Hello'
Поиск и проверка
const text = 'JavaScript — лучший язык';
// Поиск подстроки
console.log(text.includes('Java')); // true
console.log(text.startsWith('Java')); // true
console.log(text.endsWith('язык')); // true
console.log(text.indexOf('лучший')); // 14 (-1 если не найдено)
console.log(text.lastIndexOf('а')); // 22
// Поиск по RegExp
console.log(text.search(/\w+/)); // 0 (индекс первого совпадения)
console.log(text.match(/\w+/g)); // массив всех слов
Трансформация
const raw = ' Hello World ';
// Приведение регистра
console.log(raw.toLowerCase()); // ' hello world '
console.log(raw.toUpperCase()); // ' HELLO WORLD '
// Обрезка пробелов
console.log(raw.trim()); // 'Hello World'
console.log(raw.trimStart()); // 'Hello World '
console.log(raw.trimEnd()); // ' Hello World'
// Замена
console.log('foo bar foo'.replace('foo', 'baz')); // 'baz bar foo'
console.log('foo bar foo'.replaceAll('foo', 'baz')); // 'baz bar baz'
// Разбивка и объединение
console.log('a,b,c'.split(',')); // ['a', 'b', 'c']
console.log(['a','b','c'].join('-')); // 'a-b-c'
// Повторение и дополнение
console.log('*'.repeat(5)); // '*****'
console.log('5'.padStart(3, '0')); // '005'
console.log('42'.padEnd(5, '.')); // '42...'
Извлечение подстрок
const str = 'JavaScript';
// slice(start, end) — поддерживает отрицательные индексы
console.log(str.slice(0, 4)); // 'Java'
console.log(str.slice(-6)); // 'Script'
console.log(str.slice(4, -1)); // 'Scrip'
// substring(start, end) — не поддерживает отрицательные (заменяет на 0)
console.log(str.substring(0, 4)); // 'Java'
Template literals
const user = { name: 'Иван', age: 30 };
// Интерполяция
const greeting = `Привет, ${user.name}! Тебе ${user.age} лет.`;
// Многострочность
const html = `
<div class="card">
<h2>${user.name}</h2>
<p>Возраст: ${user.age}</p>
</div>
`.trim();
// Выражения внутри ${}
const discount = 10;
const price = 100;
console.log(`Итого: ${price * (1 - discount / 100)} руб`); // 'Итого: 90 руб'
// Tagged templates
function highlight(strings, ...values()) {
return strings.reduce((result, str, i) => {
return result + str + (values[i] ? `<b>${values[i]}</b>` : '');
}, '');
}
console.log(highlight`Привет, ${user.name}! Возраст: ${user.age}`);
// 'Привет, <b>Иван</b>! Возраст: <b>30</b>'
Частые ошибки
- Сравнение через
==:'5' == 5— true из-за приведения. Используйте===. - Мутация строки: строки иммутабельны, все методы возвращают новую строку — результат нужно сохранять.
indexOfвозвращает -1, неfalse:if (str.indexOf('x'))— true даже если результат -1. Проверяйте!== -1или используйтеincludes.- Длина строки с emoji:
'😀'.length === 2(два UTF-16 code unit). Для работы с Unicode-символами используйте[...'😀'].length === 1.
Связанные темы
Ресурсы
🎓 Источник: Work with strings, templates and Unicode in JavaScript
- 📅 2018-10-18 · YouTube
- Тезисы: строки в JS хранятся в UTF-16. Template literals — это синтаксический сахар; tagged templates позволяют делать DSL (SQL builders, i18n). Unicode-нормализация через
String.prototype.normalize()
⚡ Источник: Тип String согласно спецификации ECMAScript. Часть 1 из 3 · AsForJS
- 📅 2025-06-14 · YouTube
- Тезисы:
- В спеке String — последовательность 16-битных целых (UTF-16 code units), а НЕ символов
'😀'.length === 2— это 2 surrogate pair, не баг- Базовый набор операций:
[[Get]]по индексу,length,Symbol.iterator(умеет работать с surrogate)
⚡ Источник: Тип String и его две основные проблемы. Часть 2 из 3 · AsForJS
- 📅 2025-06-23 · YouTube
- Тезисы: проблема 1 — surrogate pairs (emoji, кириллица в редких случаях). Проблема 2 — normalization (NFC vs NFD): два визуально одинаковых "é" могут быть
'é'и'é'
⚡ Источник: String in wild. Часть 3 из 3 · AsForJS
- 📅 2025-06-26 · YouTube
- Тезисы: в V8 строки хранятся как ConsString (склейка), SlicedString (срез), ExternalString (от C++).
str1 + str2создаёт ConsString с O(1), но первое чтение требует O(n) flatten
⚡ Источник: Побалакаємо щодо String в JavaScript · AsForJS
- 📅 2025-06-04 · YouTube
- Тезисы: обзорная беседа о специфике String — почему
'a' === 'a'(string interning в V8), почемуnew String('a') !== 'a'(object vs primitive)
⚡ Источник: JavaScript template literal или 100+1 способ вызвать функцию · AsForJS
- 📅 2023-05-29 · YouTube
- Тезисы: tagged template literal — это вызов функции с особыми аргументами:
[strings, ...values()].stringsимеет.rawдля доступа к исходному тексту. Это основа для GraphQL/styled-components
⚡ Источник: Задача с собеседования о разбиении текста на строки · AsForJS
- 📅 2023-06-12 · YouTube
- Тезисы: разбор word-wrap. Подход: парсер по словам, не по индексам. Учёт переносов и многострочного режима
⚡ Источник: ⎡RegExp 05⎦ JavaScript Strings и Unicode, UTF-16 · AsForJS
- 📅 2023-07-04 · YouTube
- Тезисы: Unicode code point ≠ UTF-16 code unit.
\u{1F600}(code point) vs😀(две UTF-16 unit). RegExp flaguвключает code point matching