Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 53 additions & 18 deletions modules/31-advanced-strings/25-interpolation/ru/README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,50 @@
Конкатенация строк через `+` работает, но читать такой код неудобно:
Вспомним, как работает конкатенация. Для этого мы соединяем нужные строки (или переменные со строками внутри) с помощью знака `+`:

```javascript
const greeting = 'Здравствуйте';
const firstName = 'Анна';
const firstName = 'Joffrey';
const greeting = 'Hello';

console.log(greeting + ', ' + firstName + '!');
// => Здравствуйте, Анна!
// => Hello, Joffrey!
```

Чем длиннее строка, тем сложнее уследить за кавычками и плюсами.
Но в сложных выражениях становится трудно сразу увидеть, какой текст получится на выходе. Особенно если в строке используются пробелы, запятые или кавычки: они начинают мешать восприятию. Даже текущий пример требует небольшого напряжения, чтобы понять, какой получится результат.

## Интерполяция

Вместо конкатенации можно использовать **шаблонные строки** (template literals). Они записываются в обратных кавычках `` ` ``, а переменные вставляются с помощью `${}`:
По этой причине во многих языках существует операция, которая называется интерполяцией. Интерполяция представляет собой способ встраивать значения переменных прямо внутрь строки. В JavaScript для этого используют **шаблонные строки** (template literals). Они записываются в обратных кавычках `` ` ``, а переменные вставляются с помощью `${}`:

```javascript
const greeting = 'Здравствуйте';
const firstName = 'Анна';
const firstName = 'Joffrey';
const greeting = 'Hello';

console.log(`${greeting}, ${firstName}!`);
// => Hello, Joffrey!
```

Обратные кавычки указывают, что внутри строки можно использовать переменные. Их имена записываются в `${}`, и JavaScript автоматически подставляет нужные значения.

```text
firstName = 'Joff'
greeting = 'Hello'

`${greeting}, ${firstName}!`
└───┬───┘ └────┬────┘
'Hello' 'Joff'
└──────┬────────┘
'Hello, Joff!'
```

Сравните эти два примера рядом:

```javascript
console.log(greeting + ', ' + firstName + '!');
console.log(`${greeting}, ${firstName}!`);
// => Здравствуйте, Анна!
```

Результат тот же, но код читается гораздо проще.
Второй вариант проще и понятнее.

## Как это работает

Всё, что находится внутри `${}`, вычисляется как JavaScript-выражение, а результат вставляется в строку.
Всё, что находится внутри `${}`, вычисляется как JavaScript-выражение, а результат вставляется в строку. Поэтому внутри можно использовать не только переменные, но и любые выражения: арифметику, вызовы функций и так далее.

```javascript
const price = 100;
Expand All @@ -36,13 +54,30 @@ console.log(`Итого: ${price * count} рублей`);
// => Итого: 300 рублей
```

Внутри `${}` можно использовать не только переменные, но и любые выражения: арифметику, вызовы функций, условия.

## Обратные кавычки — ключ

Шаблонная строка **обязательно** записывается в обратных кавычках `` ` ``. Одинарные или двойные кавычки не работают:
Шаблонная строка **обязательно** записывается в обратных кавычках `` ` ``. Одинарные или двойные кавычки для интерполяции не работают:

```javascript
console.log('${firstName}'); // выведет буквально: ${firstName}
console.log(`${firstName}`); // выведет значение переменной
```

## Пример

```javascript
console.log('${firstName}'); // выведет буквально: ${firstName}
console.log(`${firstName}`); // выведет значение переменной
const school = 'Hexlet';

const whatIsIt = `${school} - online courses`;
console.log(whatIsIt); // => Hexlet - online courses
```

Такая запись легко читается: пробелы, дефисы и символы видны сразу. Строка выглядит именно так, как она появится в выводе. Это делает код понятным и удобным в поддержке.

## Почему это важно

Интерполяция предпочтительнее конкатенации почти во всех современных языках программирования. Она:

- упрощает структуру строк;
- улучшает читаемость кода;
- снижает количество ошибок при работе с пробелами и знаками препинания.
90 changes: 72 additions & 18 deletions modules/31-advanced-strings/30-symbols/ru/README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,92 @@
Строка в JavaScript — это последовательность символов. К каждому символу можно обратиться по его **индексу** — порядковому номеру, начиная с нуля.
Иногда нужно получить один символ из строки. Например, если сайт знает имя и фамилию пользователя и нужно вывести их в сокращённом формате вида `A. Ivanov`. Для этого потребуется взять первую букву имени.

В JavaScript для доступа к символам строки используют индексацию. Индексация означает, что у каждого символа в строке есть свой номер, то есть индекс. Индексация начинается с нуля: у первого символа индекс `0`, у второго `1` и так далее. Представим, что у нас есть строка:

Check notice on line 3 in modules/31-advanced-strings/30-symbols/ru/README.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] modules/31-advanced-strings/30-symbols/ru/README.md#L3

Use “an” instead of ‘a’ if the following word starts with a vowel sound, e.g. ‘an article’, ‘an hour’. (EN_A_VS_AN) Suggestions: `an` URL: https://languagetool.org/insights/post/indefinite-articles/ Rule: https://community.languagetool.org/rule/show/EN_A_VS_AN?lang=en-US Category: MISC
Raw output
modules/31-advanced-strings/30-symbols/ru/README.md:3:391: Use “an” instead of ‘a’ if the following word starts with a vowel sound, e.g. ‘an article’, ‘an hour’. (EN_A_VS_AN)
 Suggestions: `an`
 URL: https://languagetool.org/insights/post/indefinite-articles/ 
 Rule: https://community.languagetool.org/rule/show/EN_A_VS_AN?lang=en-US
 Category: MISC

```javascript
const firstName = 'Alexander';
```

Чтобы получить первую букву, указываем её позицию (индекс) в квадратных скобках:

```javascript
console.log(firstName[0]); // => A
```

Индексы в JavaScript (и во многих языках) начинаются с нуля:

```text
Символ A l e x a n d e r
Индекс 0 1 2 3 4 5 6 7 8
```

Длина строки `Alexander` равна `9`, поэтому индекс последнего символа равен `8`, то есть `9 - 1`. Длину строки можно узнать через свойство `length`:

```javascript
const language = 'JavaScript';
console.log(firstName.length); // => 9
console.log(firstName[firstName.length - 1]); // => r
```

Если изменится длина строки, то последний символ тоже сдвинется, и придётся снова вычислять его индекс.

console.log(language[0]); // => J
console.log(language[4]); // => S
console.log(language[9]); // => t
## Выход за границы строки

В отличие от некоторых языков, в JavaScript обращение к несуществующему индексу не вызывает ошибку — возвращается специальное значение `undefined`:

```javascript
console.log(firstName[9]); // => undefined
```

Первый символ имеет индекс `0`, второй — `1`, и так далее.
Поэтому в программировании принято проверять длину строки и обращаться к её символам, только если это безопасно. Мы дойдём до этого в будущих уроках.

## Отрицательные индексы
## Извлечение символов с конца

В JavaScript нет отрицательных индексов (в отличие от Python). Чтобы получить последний символ, нужно вычислить индекс явно:
В некоторых языках (например, в Python) для доступа к символам с конца используют отрицательные индексы. В JavaScript квадратные скобки отрицательные индексы **не** понимают — `firstName[-1]` вернёт `undefined`. Зато есть метод `at()`, который их поддерживает:

Check notice on line 43 in modules/31-advanced-strings/30-symbols/ru/README.md

View workflow job for this annotation

GitHub Actions / LanguageTool

[LanguageTool] modules/31-advanced-strings/30-symbols/ru/README.md#L43

Unpaired symbol: ‘'’ seems to be missing (EN_UNPAIRED_QUOTES) URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US Category: PUNCTUATION
Raw output
modules/31-advanced-strings/30-symbols/ru/README.md:43:229: Unpaired symbol: ‘'’ seems to be missing (EN_UNPAIRED_QUOTES)
 URL: https://languagetool.org/insights/post/punctuation-guide/#what-are-parentheses 
 Rule: https://community.languagetool.org/rule/show/EN_UNPAIRED_QUOTES?lang=en-US
 Category: PUNCTUATION

```javascript
const word = 'hello';
console.log(word[word.length - 1]); // => o
const word = 'Hexlet';

console.log(word.at(-1)); // => t, последний символ
console.log(word.at(-2)); // => e, предпоследний символ
```

## Что происходит при выходе за границы
```text
Строка: 'H' 'e' 'x' 'l' 'e' 't'
Индекс: 0 1 2 3 4 5
С конца: -6 -5 -4 -3 -2 -1
```

Метод `at()` работает так:

- `at(-1)` соответствует последнему символу;
- `at(-2)` соответствует предпоследнему;
- и так далее.

Если индекс больше или равен длине строки, вернётся `undefined`:
Это удобно и безопасно, потому что работает правильно даже если строка меняет свою длину.

Индекс можно хранить в переменной:

```javascript
console.log('hi'[10]); // => undefined
const index = 0;
console.log(word[index]); // => H
```

## Управляющие символы тоже считаются
Такой подход полезен, когда индекс вычисляется где-то в коде, а потом используется для доступа к нужному символу.

## Спецсимволы

При индексации учитываются обычные буквы, знаки и спецсимволы. Все они занимают позицию в строке и имеют свой индекс, даже если их «не видно» на экране.

Например, в строке `'\nyou'` первый символ представляет собой `\n` (перенос строки), а под индексом `1` уже идёт буква `y`. Поэтому обращение `magic[1]` вернёт именно `y`.

Символ `\n` (перевод строки) — это один символ, даже если в коде он выглядит как два.
## Подумайте: что выведет этот код?

```javascript
const text = 'Na\nharis';
// N=0, a=1, \n=2, h=3, a=4, r=5, i=6, s=7
console.log(text[7]); // => s
const magic = '\nyou';
console.log(magic[1]); // => ?
```

Вывод будет:

```text
y
```
116 changes: 97 additions & 19 deletions modules/31-advanced-strings/70-slices/ru/README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,118 @@
Когда нужно извлечь часть строки, используют метод `slice()`.
Работая со строками, мы часто сталкиваемся с задачей: извлечь часть строки. Например, получить год из даты, имя из полного ФИО или первые несколько символов из адреса электронной почты. Для таких случаев в JavaScript есть удобный инструмент — метод `slice()`.

```javascript
const text = 'Hello, World!';
## Что такое подстрока?

Подстрока является частью строки — тем, что входит внутрь другой строки. Например, в строке `'12-08-2034'` подстрокой может быть `'2034'`, `'12'` или даже `'-'`. Всё зависит от того, какую информацию нам нужно извлечь.

Допустим, у нас есть строка с датой `'12-08-2034'`. Мы хотим получить из неё только год `'2034'`. В этой строке каждый символ имеет индекс (позицию), начиная с нуля:

```text
'1' '2' '-' '0' '8' '-' '2' '0' '3' '4'
0 1 2 3 4 5 6 7 8 9
```

Год начинается с индекса 6 и заканчивается на 9. Чтобы извлечь его, мы используем `slice()`:

console.log(text.slice(7)); // => World! (с индекса 7 до конца)
console.log(text.slice(7, 12)); // => World (с 7 по 12, не включая 12)
console.log(text.slice(0, 5)); // => Hello
```javascript
const value = '12-08-2034';
const year = value.slice(6, 10);
console.log(year); // => 2034
```

## Синтаксис
Вызов `value.slice(6, 10)` берёт символы с индекса 6 по 9 включительно. Формат:

```text
str.slice(start) — от start до конца
str.slice(start, end) — от start до end (end не включается)
строка.slice(начало, конец)
```

Символ с индексом, указанным как «конец», не включается. Его можно воспринимать как порядковый номер символа, перед которым нужно остановиться.

```javascript
const value = 'code-basics';

console.log(value.slice(5, 11)); // => basics (с 5 по 10 индекс)
console.log(value.slice(0, 7)); // => code-ba (с 0 по 6 индекс)
console.log(value.slice(2, 6)); // => de-b
```

## Срез возвращает строку

`slice()` всегда возвращает строку, даже если в ней только цифры. Это значит, что результат можно использовать как обычную строку: конкатенировать, выводить, передавать в функции и снова резать:

```javascript
const value = '01-12-9873';

const part = value.slice(3, 7); // => 12-9
console.log(part.slice(0, 2)); // => 12
```

Индексация начинается с нуля — как при обращении к символам.
Сначала мы получили подстроку `'12-9'`, а потом сделали из неё новый срез `'12'`.

## Срез до конца или с начала

Если второй аргумент не указать, `slice()` вернёт всё от стартового индекса до конца строки. А `slice(0)` или `slice()` без аргументов вернёт строку целиком:

```javascript
const value = 'Hexlet';

console.log(value.slice(3)); // => let // с 3 символа до конца
console.log(value.slice(0, 3)); // => Hex // от начала до 3 символа
console.log(value.slice()); // => Hexlet // вся строка
```

## Отрицательные индексы

`slice()` поддерживает отрицательные индексы: `-1` — последний символ, `-2` — предпоследний и так далее.
`slice()` умеет считать и с конца строки. Для этого используются отрицательные индексы: `-1` соответствует последнему символу, `-2` — предпоследнему и так далее. Это удобно, когда заранее неизвестна длина строки, но нужно взять «хвост» или «середину» относительно конца:

```javascript
const word = 'JavaScript';
const value = 'Hexlet';

console.log(word.slice(-6)); // => Script
console.log(word.slice(-6, -3)); // => Scr
console.log(value.slice(-1)); // => t // последний символ
console.log(value.slice(3, -1)); // => le // от 3 до предпоследнего
console.log(value.slice(-3)); // => let // последние три символа
```

## Практический пример
## Срез с переменными

Убрать протокол из URL:
Границы среза не обязаны быть жёстко зафиксированы числами. Можно использовать переменные:

```javascript
const url = 'https://hexlet.io';
console.log(url.slice(8)); // => hexlet.io
const start = 1;
const end = 5;

const value = 'Hexlet';
console.log(value.slice(start, end)); // => exle
```

Это особенно полезно, когда границы вычисляются во время работы программы.

## Чего нет у slice()

В некоторых языках (например, в Python) у среза есть третий параметр — шаг, и им можно, например, взять каждый второй символ или развернуть строку. У метода `slice()` шага нет. Поэтому такие задачи в JavaScript решают иначе:

- развернуть строку можно так:

```javascript
const value = 'Hexlet';
console.log(value.split('').reverse().join('')); // => telxeH
```

- взять каждый второй символ — с помощью цикла (к циклам мы вернёмся позже).

Существует и похожий метод `substring()`. Он работает почти как `slice()`, но не понимает отрицательные индексы (трактует их как `0`), поэтому для извлечения «хвоста» строки удобнее `slice()`.

## Быстрая шпаргалка

```javascript
const value = 'Hexlet';

value.slice(); // Hexlet — вся строка
value.slice(0); // Hexlet
value.slice(5); // t
value.slice(0, 5); // Hexle
value.slice(-1); // t — последний символ
value.slice(-3); // let — последние три символа
value.slice(2, -1); // xle — с третьего до предпоследнего
```

`'https://'` занимает 8 символов, поэтому `slice(8)` возвращает всё, начиная с 9-го символа.
Не переживайте, если сейчас не запомните все комбинации: вы быстро начнёте использовать их на практике. Главное — понимать базовую структуру `строка.slice(начало, конец)`.
Loading
Loading