diff --git a/modules/25-strings/10-quotes/index.js b/modules/25-strings/10-quotes/index.js index 2d308b6c..91104f22 100644 --- a/modules/25-strings/10-quotes/index.js +++ b/modules/25-strings/10-quotes/index.js @@ -1 +1 @@ -console.log('"Khal Drogo\'s favorite word is "athjahakar""'); +console.log('The file "user\'s_config.json" was not found.'); diff --git a/modules/25-strings/10-quotes/ru/EXERCISE.md b/modules/25-strings/10-quotes/ru/EXERCISE.md index e687f6c7..0ad2855a 100644 --- a/modules/25-strings/10-quotes/ru/EXERCISE.md +++ b/modules/25-strings/10-quotes/ru/EXERCISE.md @@ -1,12 +1,7 @@ - -Напишите программу, которая выведет на экран: - -``` -"Khal Drogo's favorite word is "athjahakar"" -``` - -Программа должна в точности вывести на экран именно эту фразу. Обратите внимание на кавычки в начале и в конце фразы: +Программа не нашла нужный файл и вывела сообщение с его названием. Напишите программу, которая выводит то же самое сообщение: ```text -"Khal Drogo's favorite word is "athjahakar"" +The file "user's_config.json" was not found. ``` + +Строка содержит и апостроф, и двойные кавычки — выберите подходящий способ их записи. diff --git a/modules/25-strings/10-quotes/ru/README.md b/modules/25-strings/10-quotes/ru/README.md index 2ed57ef1..3917ef24 100644 --- a/modules/25-strings/10-quotes/ru/README.md +++ b/modules/25-strings/10-quotes/ru/README.md @@ -1,3 +1,8 @@ +Строки в программировании на JavaScript используются очень часто и в самых разных ситуациях. С их помощью мы работаем с текстом, выводим сообщения на экран, обрабатываем пользовательский ввод и взаимодействуем с внешними системами. + +![Строки](./assets/strings.png) + +С точки зрения JavaScript строка представляет собой просто набор символов, заключённый в кавычки. Посмотрим на примеры. ```javascript 'Hello' @@ -7,81 +12,93 @@ '' ``` -Какие из этих пяти вариантов — строки? +Все эти варианты являются строками. + +- `'Hello'`, `'Goodbye'` и `'G'` представляют собой строки из нескольких или одного символа. +- `' '` является строкой, состоящей из одного пробела. +- `''` является пустой строкой, в ней нет ни одного символа. Играет такую же роль, как 0 в математике. + +То есть всё, что находится внутри кавычек, считается строкой, даже если там только пробел или вообще ничего нет. -С первыми двумя все понятно, это точно строки, мы уже работали с подобными конструкциями и говорили, что строки - это наборы символов. +## Терминология. Строка или строчка? -Любой одиночный символ в кавычках — это строка. Пустая строка `''` — это тоже строка. То есть строкой мы считаем всё, что находится внутри кавычек, даже если это пробел, один символ или вообще отсутствие символов. +В программировании есть терминологическая ловушка. -Ранее в уроках мы записывали строки в одинарных кавычках, но это не единственный способ. Можно использовать и двойные: +- Строка (string) является типом данных (то что разбирали выше), например `'hello'`. +- Строчка (line) является строкой текста в файле или в коде. + +Например, в коде ниже есть строчка, но не строка. ```javascript -// Стандарт кодирования airbnb, рекомендует -// использовать, по возможности, одинарные -console.log("Dracarys!"); +console.log(5); ``` -Представьте, что вы хотите напечатать строчку _Dragon's mother_. Апостроф перед буквой **s** — это такой же символ, как одинарная кавычка. Попробуем: +Чтобы избежать путаницы, в этом курсе мы будем использовать такие формулировки. + +- Строка, когда говорим о типе данных. +- Строчка, когда речь идёт о строках кода. + +## Одинарные и двойные кавычки + +В JavaScript строки можно записывать как в одинарных, так и в двойных кавычках. + +```javascript +console.log('Hello'); +console.log("Hello"); +``` + +По умолчанию принято использовать одинарные кавычки `'`, если внутри строки не требуется двойных. Этого стиля придерживается популярный стандарт оформления кода от [AirBnb](https://github.com/airbnb/javascript). + +## Проблема с кавычками внутри строки + +Представьте, что вы хотите напечатать строку *Dragon's mother*. В ней есть апостроф (*'s*), совпадающий с символом одинарной кавычки. Попробуем так. ```javascript console.log('Dragon's mother'); // Uncaught SyntaxError: missing ) after argument list ``` -Такая программа не будет работать. С точки зрения JavaScript, строка началась с одинарной кавычки, а потом закончилась после буквы **n**. Дальше были символы `s mother` без кавычек — значит, это не строка. А потом была одна открывающая строку кавычка, которая так и не закрылась: `');`. Этот код синтаксически некорректен (это видно даже по тому, как подсвечен код). - -Здесь нам помогут двойные кавычки. Такой вариант программы отработает корректно: +JavaScript решит, что строка заканчивается после слова `Dragon`, а остальное не распознает как валидный код, что вызовет синтаксическую ошибку. Чтобы избежать этого, обернём строку в двойные кавычки. ```javascript console.log("Dragon's mother"); ``` -Теперь интерпретатор знает, что строка началась с двойной кавычки — значит, и закончиться должна на двойной кавычке. А одинарная кавычка внутри стала частью строки. +Теперь JavaScript понимает, что одинарная кавычка внутри строки является обычным символом, а сама строка начинается и заканчивается двойными кавычками. -Верно и обратное. Если внутри строки мы хотим использовать двойные кавычки, то саму строку надо делать в одинарных. Причем количество кавычек внутри самой строки не важно. +Если внутри строки нужны двойные кавычки, а снаружи одинарные, проблем тоже не будет. -А что, если мы хотим создать такую строку: +```javascript +console.log('He said "No"'); +``` + +Иногда в строке встречаются оба типа кавычек. ``` Dragon's mother said "No" ``` -В ней есть и одинарные и двойные кавычки. Как быть в этой ситуации? Нужно каким-то образом сказать интерпретатору считать каждую кавычку частью строки, а не началом или концом строки. - -Для этого **экранируют** специальные символы. В нашем случае тот символ, который является признаком конца и начала строки, это либо одинарная кавычка, либо двойная, в зависимости от ситуации. Для экранирования используется обратный слеш `\`. +В этом случае, чтобы JavaScript не спутал кавычки внутри строки с внешними, используют символ экранирования — обратный слэш `\`. Он говорит интерпретатору, что следующий за ним символ является частью строки, а не управляющим символом. ```javascript -// Экранируется только ", так как в этой ситуации -// двойные кавычки имеют специальное значение console.log("Dragon's mother said \"No\""); // => Dragon's mother said "No" ``` -Посмотрите внимательно: нам нужно было добавить `\` для двойных кавычек, но не для одинарной (апостроф), потому что сама строка создана с двойными кавычками. Если бы строка создавалась с одинарными кавычками, то символ экранирования нужен был бы перед апострофом, но не перед двойными кавычками. +Здесь мы экранируем двойные кавычки внутри строки, заключённой в двойные кавычки. + +То же самое работает и в обратном случае. ```javascript -// \ не выводится, если после него идет обычный, -// а не специальный символ -console.log("Death is \so terribly final"); -// => Death is so terribly final +console.log('Dragon\'s mother said "No"'); +// => Dragon's mother said "No" ``` -А что, если нужно вывести сам обратный слеш? Точно так же, как и любой другой специальный символ, его надо экранировать самим собой. +## Как вывести обратный слэш + +Чтобы вывести сам обратный слэш, его тоже нужно экранировать. ```javascript console.log("\\"); // => \ ``` - -Вопрос на самопроверку, что выведет этот код? - -```javascript -console.log("\\ \\ \\\\ \\\ \'\""); -``` - -
-Ответ - -Этот код выведет такую строку: `\ \ \\ \ '"`. - -
diff --git a/modules/25-strings/10-quotes/ru/assets/strings.png b/modules/25-strings/10-quotes/ru/assets/strings.png new file mode 100644 index 00000000..4cce3286 Binary files /dev/null and b/modules/25-strings/10-quotes/ru/assets/strings.png differ diff --git a/modules/25-strings/10-quotes/ru/data.yml b/modules/25-strings/10-quotes/ru/data.yml index d647b3c1..43a6fe29 100644 --- a/modules/25-strings/10-quotes/ru/data.yml +++ b/modules/25-strings/10-quotes/ru/data.yml @@ -2,5 +2,5 @@ name: Кавычки tips: - > - [Шаблонные - строки](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/template_strings) + [Строки в + JavaScript](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String) diff --git a/modules/25-strings/10-quotes/test.js b/modules/25-strings/10-quotes/test.js index 7556ba0b..ac4a9568 100644 --- a/modules/25-strings/10-quotes/test.js +++ b/modules/25-strings/10-quotes/test.js @@ -8,5 +8,5 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); - expect(firstArg).toBe('"Khal Drogo\'s favorite word is "athjahakar""'); + expect(firstArg).toBe('The file "user\'s_config.json" was not found.'); }); diff --git a/modules/25-strings/15-escape-characters/index.js b/modules/25-strings/15-escape-characters/index.js index 26f2390d..0789496d 100644 --- a/modules/25-strings/15-escape-characters/index.js +++ b/modules/25-strings/15-escape-characters/index.js @@ -1 +1,3 @@ -console.log('- Did Joffrey agree?\n- He did. He also said "I love using \\n".'); +console.log( + 'Для разделения строк используйте "\\n"\nПример: console.log("строка1\\nстрока2")', +); diff --git a/modules/25-strings/15-escape-characters/ru/EXERCISE.md b/modules/25-strings/15-escape-characters/ru/EXERCISE.md index 0c64edc3..9ffec32b 100644 --- a/modules/25-strings/15-escape-characters/ru/EXERCISE.md +++ b/modules/25-strings/15-escape-characters/ru/EXERCISE.md @@ -1,9 +1,8 @@ - -Напишите программу, которая выводит на экран: +Вы пишете программу, которая показывает пользователю подсказку о том, как разбить текст на строки. Выведите подсказку одним вызовом `console.log()`: ```text -- Did Joffrey agree? -- He did. He also said "I love using \n". +Для разделения строк используйте "\n" +Пример: console.log("строка1\nстрока2") ``` -При этом программа использует только один `console.log()`, но результат на экране должен выглядеть в точности, как показано выше. +Обратите внимание: `\n` в первой строке — это буквальный текст, а не перевод строки. diff --git a/modules/25-strings/15-escape-characters/ru/README.md b/modules/25-strings/15-escape-characters/ru/README.md index daa23c16..b6b55d95 100644 --- a/modules/25-strings/15-escape-characters/ru/README.md +++ b/modules/25-strings/15-escape-characters/ru/README.md @@ -1,49 +1,35 @@ - -Мы хотим показать диалог Матери Драконов со своим ребёнком: +Допустим, мы хотим вывести текст ниже в две строчки. ```text - Are you hungry? - Aaaarrrgh! ``` -Если вывести на экран строку с таким текстом: +Если мы просто передадим этот текст в `console.log()`, то JavaScript напечатает всё в одну строчку. Технически можно написать два подряд идущих `console.log()`, но представим, что мы хотим это сделать с помощью одного. ```javascript console.log('- Are you hungry?- Aaaarrrgh!'); +// => - Are you hungry?- Aaaarrrgh! ``` -то получится так: - -```text -- Are you hungry?- Aaaarrrgh! -``` - -Не то, что мы хотели. Строки расположены друг за другом, а не одна ниже другой. Нам нужно как-то сказать интерпретатору «нажать на энтер» — сделать перевод строки после вопросительного знака. Это можно сделать, используя символ перевода строки: `\n`. +Чтобы каждая из них начиналась с новой строки, нужно добавить перевод строки, то есть «нажать Enter». В программировании это реализуется через добавление специальных символов, в данном случае `\n`. Да, это не опечатка. Несмотря на то, что мы видим здесь два символа, с точки зрения JavaScript это один символ. ```javascript console.log('- Are you hungry?\n- Aaaarrrgh!'); ``` -результат: +Результат будет таким. ```text - Are you hungry? - Aaaarrrgh! ``` -`\n` — это специальный символ. В литературе его часто обозначают как *LF* (Line Feed). Возможно вы сейчас подумали, что это опечатка, ведь здесь мы видим два символа `\` и `n`, но это не так. С точки зрения компьютера — это один невидимый символ перевода строки. Доказательство: - -```javascript -// Мы это не изучали, но вы должны знать правду -// Ниже код, который возвращает длину строки -'a'.length; // 1 -'\n'.length; // 1 !!! -'\n\n'.length; // 2 !!! -``` +## Что такое `\n`? -Почему так сделано? `\n` — всего лишь способ записать символ перевода строки, но сам перевод строки по своему смыслу – это один символ, правда, невидимый. Именно поэтому и возникла такая задача. Нужно было как-то представить его на клавиатуре. А поскольку количество знаков на клавиатуре ограничено и отдано под самые важные, то все специальные символы реализуются в виде таких обозначений. +`\n` является управляющей последовательностью (англ. escape sequence, иногда говорят «экранированная последовательность»). Она обозначает перевод строки, но не отображается напрямую. Вы не увидите `\n` в выводе программы, так как она влияет только на расположение текста. -Символ перевода строки не является чем-то специфичным для программирования. Все, кто хоть раз печатал на компьютере, использовал перевод строки, нажимая на Enter. Во многих редакторах есть опция, позволяющая включить отображение невидимых символов. С помощью этой опции можно понять, где находятся невидимые символы (хотя это всего лишь схематичное отображение, у этих символов нет графического представления, они невидимые): +В текстовых редакторах при нажатии Enter добавляется невидимый символ LF (Line Feed). Именно его и означает `\n`. Иногда такие символы можно увидеть, если включить отображение спецсимволов. ```text - Привет!¶ @@ -51,78 +37,60 @@ console.log('- Are you hungry?\n- Aaaarrrgh!'); - Как дела? ``` -Устройство, которое выводит соответствующий текст, учитывает этот символ. Например, принтер при встрече с LF протаскивает бумагу вверх на одну строку, а текстовый редактор переносит весь последующий текст ниже, также на одну строку. +Принтеры, редакторы и интерпретаторы JavaScript понимают `\n` как команду начать строку с новой строки. -`\n` — это пример **экранирующей последовательности** (escape sequence). Их ещё называют управляющими конструкциями. Хотя таких символов не один десяток, в программировании часто встречаются всего несколько. Кроме перевода строки, к таким символам относятся табуляция (разрыв, получаемый при нажатии на кнопку Tab) и возврат каретки (только в Windows). Нам, программистам, часто нужно использовать перевод строки `\n` для правильного форматирования текста. +## Примеры использования `\n` -```javascript -console.log('Gregor Clegane\nDunsen\nPolliver\nChiswyck'); -``` - -На экран выведется: +Вот как JavaScript обрабатывает управляющую последовательность `\n`. ```text -Gregor Clegane -Dunsen -Polliver -Chiswyck +В коде 'Hello\nWorld' + ↓ +На экране Hello + World ``` -Обратите внимание на следующие моменты: - -1. Не имеет значения, что стоит перед или после `\n`: символ или пустая строка. Перевод будет обнаружен и выполнен в любом случае. - -2. Помните, что строка может содержать один символ или вообще ноль символов. А еще строка может содержать только `\n`. Проанализируйте следующий пример: - - ```javascript - console.log('\n'); - console.log('Dunsen'); - ``` - - Здесь мы сначала выводим строку «перевод строки», а потом делаем вывод обыкновенной строки. Программа выведет на экран: - - ```text - - Dunsen - ``` - - Почему перед строкой *Dunsen* появилось две пустые строки, а не одна? Дело в том, что `console.log()` при выводе значения автоматически добавляет в конец символ перевода строки. Таким образом, один перевод строки мы указали явно, передав этот символ экранирующей последовательности аргументом в функцию, а второй перевод строки добавлен самой функцией автоматически. - - Ещё пример кода: - - ```javascript - console.log('Polliver'); - console.log('Gregor Clegane'); - console.log(); - console.log('Chiswyck'); - console.log('\n'); - console.log('Dunsen'); - ``` - - Вывод будет таким: - - ```text - Polliver - Gregor Clegane - - Chiswyck +Местоположение `\n` меняет итоговый вывод. +```javascript +console.log('Hello\nWorld'); +// Hello +// World + +console.log('Hello \nWorld'); +// Hello +// World (в конце первой строки есть пробел) + +console.log('Hello\n World'); +// Hello +// World (во второй строке в начале пробел) + +console.log('Hello\n\nWorld'); +// Hello +// +// World (пустая строка между ними) +``` - Dunsen - ``` +Пробелы до или после `\n` также учитываются. JavaScript воспринимает их как обычные символы и отображает в выводе. - Сейчас у вас достаточно знаний, чтобы самостоятельно разобраться и понять, почему вывод сформировался именно таким образом. +## Как вывести сам символ `\n` -3. Если нам понадобится вывести `\n` именно как текст (два отдельных печатных символа), то можно воспользоваться уже известным нам способом экранирования, добавив еще один `\` в начале. То есть последовательность `\\n` отобразится как символы `\` и `n`, идущие друг за другом. +`\n` в JavaScript является управляющей последовательностью. Если вам нужно вывести именно символы `\` и `n`, а не перевод строки, их нужно экранировать. Для этого перед обратным слешем добавляют ещё один слеш. ```javascript -console.log('Joffrey loves using \\n'); +console.log('Hello\\nWorld'); +// Hello\nWorld ``` -на экран выйдет: +## Другие управляющие последовательности -```text -Joffrey loves using \n -``` +Кроме `\n`, в JavaScript есть и другие управляющие последовательности. + +- `\t` обозначает табуляцию (эквивалент клавиши Tab). +- `\r` обозначает возврат каретки (используется в Windows, но редко применяется в современном коде). +- В программировании чаще всего используют именно `\n`, его достаточно для большинства задач. + +## Важные детали -Небольшое, но важное замечание про Windows. В Windows для перевода строк по умолчанию используется `\r\n`. Такая комбинация хорошо работает только в Windows, но создаёт проблемы при переносе в другие системы (например, когда в команде разработчиков есть пользователи как Windows, так и Linux). Дело в том, что последовательность `\r\n` имеет разную трактовку в зависимости от выбранной кодировки (рассматривается позже). По этой причине, в среде разработчиков принято всегда использовать `\n` без `\r`, так как LF всегда трактуется одинаково и отлично работает в любой системе. Не забудьте настроить ваш редактор на использование `\n`. +- `\n` является одним символом, несмотря на то, что в коде он записан как два (`\` и `n`). +- На Windows по умолчанию используется комбинация `\r\n`, но в JavaScript (и вообще в кроссплатформенной разработке) принято использовать только `\n`, чтобы избежать проблем при переносе кода между системами. diff --git a/modules/25-strings/15-escape-characters/test.js b/modules/25-strings/15-escape-characters/test.js index f28480d2..a0f2859d 100644 --- a/modules/25-strings/15-escape-characters/test.js +++ b/modules/25-strings/15-escape-characters/test.js @@ -9,6 +9,6 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); expect(firstArg).toBe( - '- Did Joffrey agree?\n- He did. He also said "I love using \\n".', + 'Для разделения строк используйте "\\n"\nПример: console.log("строка1\\nстрока2")', ); }); diff --git a/modules/25-strings/20-string-concatenation/index.js b/modules/25-strings/20-string-concatenation/index.js index 419a3cd6..e01c741b 100644 --- a/modules/25-strings/20-string-concatenation/index.js +++ b/modules/25-strings/20-string-concatenation/index.js @@ -1,5 +1,5 @@ -/* eslint no-useless-concat: 0 */ - // BEGIN -console.log('Winter ' + 'came ' + 'for ' + 'the ' + 'House ' + 'of ' + 'Frey.'); +console.log( + 'https://' + 'github.com' + '/' + 'hexlet' + '/' + 'exercises-javascript', +); // END diff --git a/modules/25-strings/20-string-concatenation/ru/EXERCISE.md b/modules/25-strings/20-string-concatenation/ru/EXERCISE.md index 0b97df95..0462c8ba 100644 --- a/modules/25-strings/20-string-concatenation/ru/EXERCISE.md +++ b/modules/25-strings/20-string-concatenation/ru/EXERCISE.md @@ -1,8 +1,7 @@ +Сайт автоматически формирует ссылки на страницы репозиториев, собирая их из отдельных частей. Соберите ссылку с помощью конкатенации и выведите на экран: -Выведите на экран - -``` -Winter came for the House of Frey. +```text +https://github.com/hexlet/exercises-javascript ``` -используя конкатенацию слов. +Каждый компонент URL — отдельная строка: протокол, домен, имя владельца, имя репозитория. diff --git a/modules/25-strings/20-string-concatenation/ru/README.md b/modules/25-strings/20-string-concatenation/ru/README.md index 86791ea1..1fd9b828 100644 --- a/modules/25-strings/20-string-concatenation/ru/README.md +++ b/modules/25-strings/20-string-concatenation/ru/README.md @@ -1,46 +1,65 @@ +Часто строки нужно собирать из нескольких частей, например объединить имя и фамилию, добавить единицу измерения или составить текст из шаблона. Для этого используется операция конкатенации, то есть склеивания строк. -В веб-разработке программы постоянно оперируют строками. Всё, что мы видим на сайтах, так или иначе представлено в виде текста. Этот текст чаще всего динамический, то есть полученный из разных частей, которые соединяются вместе. Операция соединения строк в программировании называется **конкатенацией**. +## Как объединять строки + +В JavaScript строки объединяются с помощью оператора `+`. Несмотря на то, что этот оператор используется и для сложения чисел, в случае строк он означает объединение, то есть склеивание содержимого. ```javascript -// Оператор такой же, как и при сложении чисел -// но здесь он имеет другой смысл (семантику) console.log('Dragon' + 'stone'); // => Dragonstone ``` -Склеивание строк всегда происходит в том же порядке, в котором записаны операнды. Левый операнд становится левой частью строки, а правый — правой. +Порядок имеет значение. Сначала идёт левая часть (`'Dragon'`), потом правая (`'stone'`). Результат получается в том порядке, в котором указаны операнды. -Вот еще несколько примеров: +Вот как работает объединение нескольких строк: -```javascript -console.log('Kings' + 'wood'); // => Kingswood +```text +'Hello' + ', ' + 'World!' +└──┬──┘ └┬┘ └──┬───┘ + └────┬───┘ │ + 'Hello, ' + 'World!' + └──────┬───────┘ + 'Hello, World!' +``` -// Обратный порядок слов -console.log('road' + 'Kings'); // => roadKings +Примеры. -// Конкатенировать можно абсолютно любые строки -console.log("King's" + 'Landing'); // => King'sLanding +```javascript +console.log('Kings' + 'wood'); // => Kingswood +console.log('Kings' + 'road'); // => Kingsroad +// Здесь снаружи двойные кавычки, потому что внутри есть одиночная +console.log("King's" + 'Landing'); // => King'sLanding ``` -Как видите, строки можно склеивать, даже если они записаны с разными кавычками. +JavaScript позволяет объединять строки, даже если они записаны в разных кавычках. Главное, чтобы обе части были строками. -В последнем примере название города получилось с ошибкой: *King's Landing* нужно писать через пробел. Но в наших начальных строках не было пробелов, а пробелы в самом коде слева и справа от символа `+` не имеют значения, потому что они не являются частью строк. +## Пробел тоже является символом -Выхода из этой ситуации два: +При объединении JavaScript не вставляет пробелы автоматически. Если между частями должен быть пробел, его нужно указать вручную. ```javascript -// Оба способа равнозначны +// Пробел в конце первой строки +console.log("King's " + 'Landing'); // => King's Landing -// Ставим пробел в левой части -console.log("King's " + 'Landing'); // => King's Landing -// Ставим пробел в правой части -console.log("King's" + ' Landing'); // => King's Landing +// Пробел в начале второй строки +console.log("King's" + ' Landing'); // => King's Landing ``` -Пробел — такой же символ, как и другие. Чем больше пробелов, тем шире отступы: +Результат будет одинаковый. Но если пробел не добавить, то слова склеятся. -```javascript -console.log("King's " + ' Landing'); // => King's Landing +## Управляющие последовательности -console.log("King's " + ' Landing'); // => King's Landing +В строках можно использовать управляющие последовательности, например `\n` для переноса строки или `\t` для табуляции. При конкатенации они работают так же, как и любые другие символы. + +```javascript +console.log('Hello,' + '\n' + 'World!'); +// Hello, +// World! ``` + +## Заключение + +Конкатенация представляет собой объединение строк через `+`, и строки можно объединять независимо от типа кавычек. + +- Склеивание происходит строго в порядке слева направо. +- Пробелы не добавляются автоматически, их нужно включать в строки вручную. diff --git a/modules/25-strings/20-string-concatenation/test.js b/modules/25-strings/20-string-concatenation/test.js index 0d7c695e..2dcdd835 100644 --- a/modules/25-strings/20-string-concatenation/test.js +++ b/modules/25-strings/20-string-concatenation/test.js @@ -8,5 +8,5 @@ test('hello world', async () => { const firstArg = consoleLogSpy.mock.calls.join('\n'); - expect(firstArg).toBe('Winter came for the House of Frey.'); + expect(firstArg).toBe('https://github.com/hexlet/exercises-javascript'); }); diff --git a/modules/25-strings/30-encoding/ru/EXERCISE.md b/modules/25-strings/30-encoding/ru/EXERCISE.md index 6b072427..c9f56e8e 100644 --- a/modules/25-strings/30-encoding/ru/EXERCISE.md +++ b/modules/25-strings/30-encoding/ru/EXERCISE.md @@ -1,14 +1,13 @@ - -В JavaScript можно «запросить» и вывести на экран любой символ из кодировки ASCII. Например: +Программа получает числовые коды символов и выводит их на экран — это удобно, когда символ сложно набрать с клавиатуры. Найдите символы с кодами 126, 94 и 37 в таблице ASCII и выведите каждый на отдельной строке с помощью функции `String.fromCharCode()`. ```javascript -console.log(String.fromCharCode(63)); +console.log(String.fromCharCode(...)); +console.log(String.fromCharCode(...)); +console.log(String.fromCharCode(...)); ``` -На экран выведется символ с номером 63 — вопросительный знак `?`. Таким способом можно выводить любой символ. - -Найдите в интернете таблицу кодов ASCII. Можно использовать запросы типа "ascii codes table" или «коды ascii». Обычно в таких таблицах коды указаны сразу в нескольких системах счисления: десятичной, двоичной, восьмеричной и шестнадцатеричной. Нас интересует десятичный код (*dec* или *decimal*). - -Используя пример выше и найденную таблицу, выведите на экран символы `~`, `^` и `%` (каждый на своей собственной строке). +Например, символ `?` имеет код 63: -(Конечно, можно «обмануть» тесты и просто сделать что-то типа `console.log('~')`, но так будет совсем неинтересно :) +```javascript +console.log(String.fromCharCode(63)); // вывод: ? +``` diff --git a/modules/25-strings/30-encoding/ru/README.md b/modules/25-strings/30-encoding/ru/README.md index fa65857a..7f5c8dd3 100644 --- a/modules/25-strings/30-encoding/ru/README.md +++ b/modules/25-strings/30-encoding/ru/README.md @@ -1,37 +1,63 @@ +На самом базовом уровне компьютер работает только с нулями и единицами, что составляет так называемый двоичный код. Каждую единицу или ноль называют битом (от binary digit, «двоичная цифра»). -На самом глубоком уровне компьютер оперирует исключительно цифрами `0` и `1`. Это так называемый [двоичный код](https://ru.wikipedia.org/wiki/Двоичный_код), а единички и нули называются битами, от "binary digit" — «двоичная цифра». +Любые данные в компьютере представлены просто как последовательность битов, например изображения, музыка и текст. Привычные нам числа из десятичной системы тоже можно представить в двоичной форме. -Обычные, привычные нам числа в десятичной системе счисления, закодированы с помощью двоичных чисел: +- 0 → `0` +- 1 → `1` +- 2 → `10` -- 0 ← 0 -- 1 ← 1 -- 2 ← 10 -- 3 ← 11 -- 4 ← 100 -- 5 ← 101 +## Как закодировать текст? -Но как быть с текстом? Компьютер на самом деле не знает ничего о буквах, знаках пунктуации и прочих текстовых символах. Все эти символы также закодированы числами. +Компьютер не «понимает» текст. Чтобы работать с буквами и другими символами, их тоже нужно превратить в числа. Это делают с помощью кодировок, то есть таблиц, в которых каждому символу соответствует определённое число. -Можно взять английский алфавит и дать каждой букве число, начиная с единицы по порядку: +Самый простой способ состоит в том, чтобы пронумеровать буквы, начиная с 1. -- a ← 1 -- b ← 2 -- c ← 3 -- d ← 4 -- ... -- z ← 26 +- `a` → `1` +- `b` → `2` +- ...и так до `z` → `26` -Далее можно научить компьютер понимать эту таблицу и переводить текст в числа и наоборот — числа в текст: +Теперь мы можем представить слово `hello` как набор чисел. -- `hello` → `8` `5` `12` `12` `15` -- `7` `15` `15` `4` → `good` +```text +h e l l o +↓ ↓ ↓ ↓ ↓ +8 5 12 12 15 +``` -Подобные таблицы, в которых сопоставляются буквы и числа, называются кодировками. Кроме букв алфавита, в таблицы кодировок входят знаки препинания и другие полезные символы. Вы наверняка сталкивались с кодировками, например, [ASCII](https://ru.wikipedia.org/wiki/ASCII) или [UTF-8](https://ru.wikipedia.org/wiki/UTF-8). +А `good` превращается в такую последовательность. -Разные кодировки содержат различное количество символов. Изначально небольших таблиц вроде ASCII было достаточно для большинства задач. Но в ней есть только латинские буквы, несколько простых символов вроде `%` и `?` и специальные управляющие символы типа перевода строки. +```text +g o o d +↓ ↓ ↓ ↓ +7 15 15 4 +``` -С распространением компьютеров, разным странам понадобились свои, более широкие таблицы. В том числе для кириллических букв, иероглифов, арабской вязи, дополнительных математических и типографских символов, а впоследствии — даже для эмодзи-смайликов. +Программа не знает, что это слово. Она просто видит инструкцию «нужно отобразить символ с кодом 8, потом с кодом 5 и т.д.». -Сегодня в большинстве случаев используется один из вариантов [юникода](https://ru.wikipedia.org/wiki/Юникод) — *utf-8*. Он включает в себя знаки почти всех письменных языков мира. Благодаря этому, письмо, сформированное человеком в Китае на китайском, без проблем можно открыть и увидеть в первозданном виде на компьютере в Финляндии (поймет он его или нет, это уже другой вопрос). +## ASCII. Первая массовая кодировка -С кодированием текста и кодировками программисты встречаются в своей жизни регулярно. Поддержка юникода у разных языков программирования выполнена на разном уровне. Кроме того, кодировки нужно явно указывать при работе и с базами данных, и с файлами. +Первые компьютеры работали в основном с английским языком. Для него в 1960-х годах придумали таблицу ASCII, включавшую 128 символов, в том числе латинский алфавит, цифры, знаки препинания, спецсимволы (`@`, `#`, `!`, `\n`) и управляющие коды. + +Этого хватало для первых программ, но не для всего мира. + +Когда компьютеры начали использовать в других странах, возникла проблема. В ASCII нет кириллицы, иероглифов, арабского письма, ударений, валютных символов и т. д. Каждая страна или компания начала делать свою кодировку. Все эти кодировки были несовместимы между собой, что приводило к настоящему хаосу. + +## Unicode и UTF-8. Конец бардака + +Чтобы всё починить, в 1990-х начали создавать универсальную таблицу Unicode, которая содержит символы всех письменных систем мира, в том числе латинский алфавит и кириллицу, китайское и арабское письмо, математические знаки, древнеегипетское письмо и даже эмодзи. + +Внутри Unicode есть несколько форматов хранения. Наиболее распространённым из них является UTF-8. Он компактно кодирует английские символы, но может расширяться под любые другие. + +Сегодня UTF-8 является стандартом по умолчанию в интернете, JavaScript, Linux, базах данных и редакторах кода. + +## Зачем это знать программисту? + +- Вы будете работать с текстом, и ошибки кодировки по-прежнему случаются, особенно при чтении файлов, обработке данных, взаимодействии с API и базами данных. +- JavaScript по умолчанию использует Unicode для строк. +- Нужно уметь диагностировать проблемы. Например, если видите «кракозябры», это почти наверняка ошибка кодировки. + +В JavaScript можно получить символ по его числовому коду с помощью `String.fromCharCode()`: + +```javascript +console.log(String.fromCharCode(63)); // => ? +```