Строка — это текст в кавычках. Но для JavaScript она не один неделимый кусок, а ряд символов, стоящих друг за другом. До каждого из них можно дотянуться.
const word = 'привет'
word.length // 6
word[0] // 'п'
word[word.length - 1] // 'т'length хранит количество символов. Это свойство, а не метод, поэтому скобок
после него нет.
Квадратные скобки берут символ по номеру. Номер называется индексом, и счёт начинается с нуля: у первой буквы индекс 0, у второй — 1.
Отсюда главная арифметика: у последней буквы индекс на единицу меньше длины.
Шесть букв — последний индекс 5. Поэтому последний символ берут так:
word[word.length - 1].
Если промахнуться мимо строки, ошибки не будет. word[99] вернёт undefined
— то самое «тут ничего нет».
Строку нельзя изменить
Вот место, где спотыкаются почти все.
let word = 'привет'
word[0] = 'П'
word // 'привет'Строки неизменяемы. Поменять букву внутри уже готовой строки нельзя: присваивание по индексу ничего не делает.
Можно только собрать новую строку и положить её в переменную:
word = 'П' + word.slice(1) // 'Привет'То же правило касается всех методов строк ниже. Ни один из них не меняет исходную строку. Каждый возвращает новую. Если результат не сохранить, он пропадёт:
let name = ' Аня '
name.trim() // результат выброшен, name не изменилась
name = name.trim() // теперь name — 'Аня'Регистр и пробелы
'Аня'.toUpperCase() // 'АНЯ'
'АНЯ'.toLowerCase() // 'аня'
' Аня '.trim() // 'Аня'toUpperCase делает все буквы заглавными, toLowerCase — строчными. trim
срезает пробелы с обоих краёв. Пробелы внутри строки он не трогает.
Для JavaScript 'А' и 'а' — разные символы. Поэтому, когда регистр не
важен, обе строки сначала приводят к одному регистру и только потом
сравнивают.
Поиск
const text = 'заказ оплачен'
text.includes('оплачен') // true
text.startsWith('заказ') // true
text.indexOf('оплачен') // 6
text.indexOf('отменён') // -1includes отвечает «да» или «нет»: есть ли такой кусок в строке.
startsWith проверяет только начало.
indexOf отвечает номером, с которого найденный кусок начинается. Если
ничего не нашлось, он возвращает -1.
Ловушка здесь в том, что 0 — законный ответ: совпадение в самом начале.
А 0 в условии ложен. Поэтому не пишите if (text.indexOf('заказ')).
Пишите !== -1 или просто берите includes.
Вырезать кусок
const text = 'Привет, мир!'
text.slice(0, 6) // 'Привет'
text.slice(8) // 'мир!'
text.slice(-4) // 'мир!'slice вырезает кусок по индексам. Первое число — откуда, второе — докуда,
не включая его. Без второго числа — до конца. Отрицательное число
считается с конца: -4 означает «последние четыре символа».
Повторить и дополнить
'-'.repeat(5) // '-----'
'7'.padStart(3, '0') // '007'repeat склеивает строку саму с собой нужное число раз. padStart
дописывает символы слева, пока строка не станет нужной длины. Первое число —
итоговая длина, а не сколько добавить.
Перебрать символы
Раз у символов есть индексы, строку можно пройти обычным циклом for:
const word = 'да'
for (let i = 0; i < word.length; i++) {
console.log(word[i]) // 'д', потом 'а'
}Условие i < word.length, а не <=: последний индекс на единицу меньше
длины.
Если индекс не нужен, удобнее for...of. Он сам выдаёт символ за символом:
for (const letter of 'да') {
console.log(letter)
}Теперь попробуйте сами. Код выполняется прямо в браузере — нажмите «Запустить», и увидите результат через миг.