diff --git a/modules/30-variables/10-definition/ru/README.md b/modules/30-variables/10-definition/ru/README.md index 805256e7..f6e8daef 100644 --- a/modules/30-variables/10-definition/ru/README.md +++ b/modules/30-variables/10-definition/ru/README.md @@ -1,42 +1,125 @@ -Переменные — один из базовых инструментов программирования. С их помощью программы запоминают и используют данные. - -Рассмотрим пример. +Представьте, что нужно вывести фразу `Father!` два раза: ```javascript -let greeting = 'Father!'; -console.log(greeting); // => Father! +console.log('Father!'); +console.log('Father!'); ``` -Мы **определили переменную** с именем `greeting` и присвоили ей значение `'Father!'`. Теперь вместо строки `'Father!'` можно использовать имя `greeting`. +Такой способ вполне подойдёт, если фраза встречается всего пару раз. Но что, если она будет использоваться часто, в разных частях программы? Тогда придётся копировать одно и то же выражение снова и снова. + +А что будет, если фразу нужно изменить, например заменить _Father!_ на _Mother!_? Придётся искать и исправлять все вхождения вручную. Это неудобно и приводит к ошибкам. + +## Переменные + +Чтобы не дублировать одну и ту же строку, её можно сохранить в переменной и выводить её содержимое: ```javascript -let greeting = 'Father!'; -console.log(greeting); // => Father! -console.log(greeting); // => Father! +const greeting = 'Father!'; + +console.log(greeting); +console.log(greeting); +``` + +Результат: + +```text +Father! +Father! +``` + +**Переменная** представляет собой имя, за которым хранится значение. В нашем примере мы создали переменную с именем `greeting` и записали в неё строку `'Father!'`. + +```text +const greeting = 'Father!'; + +Переменная Значение +┌──────────┐ ┌──────────┐ +│ greeting │ ──→ │ 'Father!'│ +└──────────┘ └──────────┘ ``` -Значение переменной берётся в момент обращения к ней. +Строчка `const greeting = 'Father!'` читается так: «возьми значение `'Father!'` и присвой его переменной с именем `greeting`». Знак `=` здесь является оператором присваивания, а не обозначением равенства как в математике. Он кладёт значение в переменную. + +Когда мы пишем `console.log(greeting)`, движок подставляет вместо имени `greeting` то значение, которое в ней хранится. В результате на экран выводится строка `'Father!'`. + +```text +console.log(greeting) + | + v +console.log('Father!') +``` ## let и const -В JavaScript переменные объявляются двумя способами: +В JavaScript переменную перед использованием нужно объявить с помощью одного из ключевых слов — `const` или `let`: + +- `const` — для значений, которые не будут меняться; +- `let` — для значений, которые в ходе работы программы могут поменяться. + +```javascript +const greeting = 'Father!'; // меняться не будет +let score = 0; // будет меняться по ходу программы +``` + +Если не знаете, будет ли значение меняться, используйте `const`. Это хорошая практика: так код проще читать и сложнее случайно испортить данные. К `let` и константам мы ещё вернёмся в отдельных уроках. -- `let` — для значений, которые могут меняться. -- `const` — для значений, которые не будут меняться (константы). +## Имена переменных + +Имена переменных придумывает сам программист. В JavaScript можно использовать: + +- латинские буквы (a-z, A-Z), +- цифры (но не в начале), +- символы `_` и `$`. + +Примеры допустимых имён: `greeting`, `name1`, `helloWorld`. JavaScript различает строчные и заглавные буквы. Переменные `greeting`, `Greeting` и `GREETING` являются тремя разными переменными. + +## Переменные и литералы + +В коде важно различать, где мы используем переменную, а где записываем значение напрямую. Это особенно заметно на примере с `console.log()`: + +```javascript +const greeting = 'Mother!'; +console.log(greeting); // => Mother! +console.log('greeting'); // => greeting +``` + +В первом случае используется **переменная** `greeting`, и программа подставляет её значение. Во втором случае `'greeting'` заключено в кавычки, поэтому это **строковый литерал**, то есть готовое значение, написанное прямо в коде. Несмотря на то, что мы видим слово `greeting` в обоих случаях, с точки зрения движка это абсолютно разные вещи. + +Литералы представляют собой данные, записанные явно (например, `'Hello'`, `42`, `3.14`). Идентификаторы являются именами переменных и функций (например, `greeting`, `console`), которые указывают на уже существующие значения или команды. + +## Порядок использования + +Переменную нужно сначала создать (объявить и присвоить ей значение), а уже потом использовать. Если попытаться обратиться к переменной до её создания, программа выдаст ошибку: + +```javascript +console.log(name); // Ошибка: переменная ещё не определена +// ReferenceError: Cannot access 'name' before initialization +const name = 'Alice'; +``` + +А в правильном порядке всё работает: ```javascript -let currentUser = 'Alice'; // может поменяться позже -const maxAttempts = 3; // никогда не изменится +const name = 'Alice'; +console.log(name); // => Alice ``` -Если не знаете, будет ли значение меняться — используйте `const`. Это хорошая практика. +## Несколько переменных в программе + +В одной программе можно создать сколько угодно переменных. Каждая хранит свои данные и не мешает другим: -## Правила именования +```javascript +const greeting1 = 'Father!'; +console.log(greeting1); +console.log(greeting1); + +const greeting2 = 'Mother!'; +console.log(greeting2); +console.log(greeting2); +``` -Имена переменных в JavaScript: +Как понять, когда нужно несколько переменных? Количество переменных зависит от логики программы. Эта тема подробно раскрывается позже, когда мы столкнёмся с функциями и условными конструкциями. -- Могут содержать буквы, цифры, `_` и `$`. -- Не могут начинаться с цифры. -- Чувствительны к регистру: `greeting` и `Greeting` — разные переменные. +## Где создавать переменные -Имена по стилю записываются в lowerCamelCase: `firstName`, `maxLoginAttempts`. +Программисты стараются создавать переменные ближе к месту, где они используются. Это делает код более читаемым. Особенно важно это в больших программах, где переменных может быть десятки и сотни тысяч. diff --git a/modules/30-variables/11-change/ru/README.md b/modules/30-variables/11-change/ru/README.md index b8981523..08f9301d 100644 --- a/modules/30-variables/11-change/ru/README.md +++ b/modules/30-variables/11-change/ru/README.md @@ -1,6 +1,9 @@ -Переменная потому и называется переменной, что её значение можно **изменить**. +Само слово «переменная» подсказывает, что её значение может меняться. Это одна из главных причин, почему переменные вообще существуют. + +Вот простой пример: ```javascript +// greeting переводится как «приветствие» let greeting = 'Father!'; console.log(greeting); // => Father! @@ -8,23 +11,39 @@ greeting = 'Mother!'; console.log(greeting); // => Mother! ``` -Обратите внимание: ключевое слово `let` пишется только при **первом** объявлении переменной. При повторном присваивании `let` уже не нужен. +Здесь мы сначала записали в переменную одну строку (_Father!_), потом другую (_Mother!_). Имя переменной не изменилось, но значение внутри стало другим. + +```text +До: greeting ──→ 'Father!' + ╳ +После: greeting ──→ 'Mother!' +``` + +Обратите внимание: ключевое слово `let` пишется только при **первом** объявлении переменной. При повторном присваивании `let` уже не нужен — переменная уже существует, мы лишь меняем её значение. -## Зачем это нужно? +## Зачем вообще менять значение? -Переменные меняются в самых разных ситуациях: +В реальных программах переменные меняются постоянно. Вот несколько причин: -- Пользователь обновляет своё имя в профиле. -- Игровой персонаж теряет или находит жизни. -- В процессе вычислений накапливается промежуточный результат. +- Программа реагирует на действия пользователя. Например, пока вы вводите данные в форму на сайте, переменные, которые эти данные содержат, в этот момент постоянно обновляются. +- Промежуточные результаты. Часто данные проходят через серию преобразований, и на каждом этапе переменная обновляется новым значением. Подобный механизм даже есть в калькуляторах, когда промежуточные значения сохраняются с помощью клавиш `m+` или `m-`. +- Хранение состояния. Если вы пишете игру, то положение персонажа, его здоровье, счёт и текущий уровень являются переменными, которые постоянно меняются. ## const не меняется -Если переменная объявлена через `const`, её нельзя переприсвоить. +Не каждую переменную можно переприсвоить. Если переменная объявлена через `const`, её значение менять нельзя: ```javascript const greeting = 'Father!'; greeting = 'Mother!'; // TypeError: Assignment to constant variable. ``` -Поэтому для значений, которые будут меняться, используйте `let`. +Поэтому для значений, которые будут меняться, используют `let`, а для постоянных — `const`. Так работает большинство современных языков программирования: значение, которое не должно меняться, помечают отдельно. + +## Почему это важно + +Переменные представляют собой гибкий способ хранить данные, которые могут изменяться в процессе выполнения программы. Благодаря этому можно писать программы, которые ведут себя по-разному в зависимости от условий, действий пользователя или результатов вычислений. + +Но у гибкости есть и обратная сторона. Иногда сложно сразу понять, что именно записано в переменную в тот или иной момент времени. Разработчику приходится отслеживать, где и как она изменилась, особенно если код длинный. + +Именно это делают во время отладки: пытаются разобраться, почему программа работает иначе, чем задумано. Проверяют значения переменных, отслеживают порядок выполнения кода, ищут, где что-то пошло не так. diff --git a/modules/30-variables/13-variables-naming/ru/README.md b/modules/30-variables/13-variables-naming/ru/README.md index c0ef59e0..fe0c44db 100644 --- a/modules/30-variables/13-variables-naming/ru/README.md +++ b/modules/30-variables/13-variables-naming/ru/README.md @@ -1,35 +1,38 @@ -Компьютеру всё равно, как называются переменные. Но код читают люди — и для них это имеет огромное значение. - -Посмотрите на два примера. +Представьте, что у нас есть такая программа: ```javascript -const x = 'John'; -const abcd = 30; +const x = 'Father!'; +console.log(x); ``` -vs +С технической точки зрения всё работает. Мы уже видели похожие примеры, но здесь используется переменная с названием `x`. Плохие имена мешают читать и понимать код. Вот несколько примеров неудачных переменных: ```javascript -const firstName = 'John'; -const age = 30; +const a = 'John'; +const n = 42; +const ddr = 'New York'; ``` -Первый вариант написан для компьютера, второй — для человека. +Что это за переменные? Что в них хранится? Чтобы это понять, нужно читать весь остальной код и догадываться по контексту. + +Компьютеру всё равно, как называется переменная. Для него `x`, `abc`, `message` или `elephantInTheRoom` являются просто метками для хранения данных. Людям важно другое. Программисты читают код гораздо чаще, чем пишут. Поэтому имена переменных являются важной частью общения через код. -## Требования к именам +## Хорошие примеры -- Имя должно отражать содержимое, а не тип: `userName` лучше, чем `userString`. -- Используйте английский язык: `firstName`, а не `имя`. -- Не бойтесь длинных имён: `maxLoginAttempts` лучше, чем `mla`. +```javascript +const userName = 'Arya Stark'; +const unpaidOrdersCount = 3; +const maxAttempts = 5; +``` -## Сложная задача +Хорошее имя переменной помогает понять, что делает программа, не вчитываясь в каждую строчку. Особенно важно давать такие имена, смысл которых понятен без контекста, без необходимости читать весь код вокруг. -Как назвать переменную, которая хранит количество братьев и сестёр короля? +Вот несколько советов: -Какой из вариантов вы бы выбрали? +- Используйте английский язык. Это международный стандарт. Лучше писать `ordersCount` вместо `kolvoZakazov`. Если с английским пока сложно, используйте переводчик, это нормально. Со временем станет проще. +- Старайтесь, чтобы имя отражало смысл переменной. Пусть оно будет чуть длиннее, но понятное. +- Не бойтесь тратить время на подбор хорошего названия. Это инвестиция в читаемость и поддержку кода. -- `x` — непонятно ничего -- `count` — count чего? -- `siblingsCount` — понятно и точно ✓ +Среди программистов даже есть шутка: «Одними из самых трудных задач в программировании являются кэширование и придумывание имён переменным». Иногда придумать подходящее имя действительно сложно. Вот пример: как бы вы назвали переменную, в которой хранится количество неоплаченных заказов от клиентов с задолженностью за предыдущий квартал? -Именование — одна из самых сложных задач в программировании. Со временем хорошие имена приходят сами собой. +А теперь небольшое упражнение: придумайте название для переменной, в которой будет храниться «количество братьев и сестёр короля». Запишите его в блокноте или отправьте себе на почту. Только название, без объяснений. Мы вернёмся к этому заданию через несколько уроков. diff --git a/modules/30-variables/15-variables-expressions/ru/README.md b/modules/30-variables/15-variables-expressions/ru/README.md index 7b03ad00..1d3e8471 100644 --- a/modules/30-variables/15-variables-expressions/ru/README.md +++ b/modules/30-variables/15-variables-expressions/ru/README.md @@ -1,49 +1,86 @@ -Переменные делают код понятнее: промежуточные результаты получают имена. +Мы уже знаем, что выражения можно составлять из нескольких операций. Но если записать всё вычисление в одну длинную строку, код быстро становится трудным для чтения. -Сравните два варианта одного вычисления. +Например, вот такая запись работает: ```javascript -console.log(50 * 1.25 * 6.91); +const yuansCount = 50 * 1.25 * 6.91; +console.log(yuansCount); // => 431.875 ``` -vs +JavaScript легко вычислит это выражение. Но человеку читать такой код уже не так удобно. Сразу возникают вопросы: -```javascript -const eurosCount = 50; -const dollarsPerEuro = 1.25; -const yuansPerDollar = 6.91; - -const dollarsCount = eurosCount * dollarsPerEuro; -const yuansCount = dollarsCount * yuansPerDollar; -console.log(yuansCount); -``` +- Что означает `1.25`? +- Что означает `6.91`? +- Где заканчивается один шаг вычисления и начинается следующий? -Во втором варианте понятно, что происходит: конвертация евро в доллары, потом в юани. +Чтобы сделать такие вычисления понятнее, переменные можно использовать внутри других выражений. Сначала программа сохраняет промежуточный результат в переменную, а затем подставляет значение этой переменной в следующее вычисление. ## Выражения -Любое вычислимое значение — это выражение. Переменной можно присвоить выражение. +Любое вычислимое значение — это выражение. Переменной можно присвоить выражение, а не только готовое значение. ```javascript -const sum = 3 + 4; // => 7 +const sum = 3 + 4; // => 7 const text = 'Hello' + '!'; // => 'Hello!' -const doubled = sum * 2; // => 14 +const doubled = sum * 2; // => 14 +``` + +JavaScript сначала вычисляет выражение справа от `=`, а результат сохраняет в переменную слева. + +## Конвертация валют через промежуточную валюту + +Представим, что нужно перевести евро в юани, но напрямую такой курс нам недоступен. Тогда сделаем это в два шага: **евро → доллары → юани**. Так часто работают банки при оплате покупок за рубежом. + +### Шаг 1. Евро → Доллары + +Допустим, курс: 1 евро = 1.25 доллара. Хотим перевести 50 евро: + +```javascript +const dollarsPerEuro = 1.25; +const dollarsCount = 50 * dollarsPerEuro; +console.log(dollarsCount); // => 62.5 ``` -JavaScript вычисляет выражение справа, а результат сохраняет в переменную слева. +В этой строке `50 * dollarsPerEuro` является выражением, а `dollarsCount` представляет собой переменную, в которую записывается результат. JavaScript сначала вычисляет выражение, а уже потом сохраняет результат в переменную. -## Порядок определений +Движку всё равно, как записано выражение: -Переменную нужно определить **до** её использования. +```javascript +const dollarsCount = 62.5; +``` + +или ```javascript -const fullPrice = price * 2; // ReferenceError: price is not defined -const price = 100; +const dollarsCount = 50 * dollarsPerEuro; ``` -Правильный порядок: +Результат будет один и тот же. Но для человека второй вариант полезнее: по имени `dollarsCount` сразу видно, что на этом шаге мы получили сумму в долларах. + +### Шаг 2. Доллары → Юани + +Теперь переведём 50 евро в юани, используя доллар как промежуточную валюту. Допустим, курсы валют: 1 доллар = 6.91 юаня, 1 евро = 1.25 доллара. ```javascript -const price = 100; -const fullPrice = price * 2; +const dollarsPerEuro = 1.25; +const yuansPerDollar = 6.91; + +const dollarsCount = 50 * dollarsPerEuro; +const yuansCount = dollarsCount * yuansPerDollar; + +console.log(yuansCount); ``` + +Этот код длиннее, чем одна строка `50 * 1.25 * 6.91`, но читать его проще: + +- видно, что `1.25` это курс евро к доллару; +- видно, что `6.91` это курс доллара к юаню; +- видно, что `dollarsCount` является промежуточным результатом. + +Особенно это станет заметно, если не возвращаться к коду хотя бы неделю. А теперь представьте, что в проекте сотни тысяч строк кода. Если бы в таких проектах не было промежуточных переменных и вычислений, в них было бы невозможно разобраться. + +## Что нужно запомнить + +- Если выражение получается слишком длинным, его лучше разбить на несколько шагов. +- Переменные помогают сохранять промежуточные результаты и делают вычисления понятнее. +- Когда переменная используется в выражении, JavaScript подставляет её значение и продолжает вычисление. diff --git a/modules/30-variables/18-variable-concatenation/ru/README.md b/modules/30-variables/18-variable-concatenation/ru/README.md index f41c8bef..9f18be9a 100644 --- a/modules/30-variables/18-variable-concatenation/ru/README.md +++ b/modules/30-variables/18-variable-concatenation/ru/README.md @@ -1,21 +1,76 @@ -Переменные можно использовать в конкатенации так же, как и обычные строки. +Ранее мы уже склеивали строки напрямую, используя конкатенацию. Теперь сделаем то же самое, но с использованием переменных. Хорошая новость: синтаксис остаётся тем же. Просто подставляются значения переменных. + +## Склеиваем две строки напрямую + +```javascript +const what = 'Kings' + 'road'; +console.log(what); // => Kingsroad +``` + +Здесь всё просто: две строки соединяются в одну. Так работает конкатенация: оператор `+` складывает строки, создавая новую строку. + +## Склеиваем строку и переменную + +Если в переменной `first` лежит строка `'Kings'`, мы можем спокойно склеить её с другой строкой: ```javascript -const firstName = 'Kings'; -const lastName = 'road'; -console.log(firstName + lastName); // => Kingsroad +const first = 'Kings'; +const what = first + 'road'; +console.log(what); // => Kingsroad ``` -## Пример с формированием текста +JavaScript подставит значение переменной, выполнит операцию и создаст итоговую строку. -Переменные особенно полезны, когда из нескольких частей нужно собрать готовый текст. +## Склеиваем две переменные + +Точно так же можно объединить значения двух переменных, если обе содержат строки: ```javascript -const greeting = 'Здравствуйте'; -const firstName = 'Анна'; +const first = 'Kings'; +const last = 'road'; +const what = first + last; +console.log(what); // => Kingsroad +``` + +Можно добавлять и пробелы: + +```javascript +const full = first + ' ' + last; +console.log(full); // => Kings road +``` + +```text +first = 'Kings' +last = 'road' -console.log(greeting + ', ' + firstName + '!'); -// => Здравствуйте, Анна! +first + ' ' + last +└─┬──┘ └─┬┘ +'Kings' + ' ' + 'road' +└────────┬─────────┘ + 'Kings road' +``` + +## А что если переменная содержит число? + +В JavaScript оператор `+` ведёт себя по-особенному, когда с одной стороны строка, а с другой — число. В этом случае число автоматически превращается в строку, и происходит конкатенация: + +```javascript +const age = 42; +console.log('Age: ' + age); // => Age: 42 +``` + +Это удобно, но иногда приводит к неожиданностям, поэтому при желании число можно превратить в строку явно, с помощью функции `String()`: + +```javascript +const age = 42; +console.log('Age: ' + String(age)); // => Age: 42 +``` + +То же самое касается переменных с результатами вычислений: + +```javascript +const price = 50 * 1.25 * 6.91; // => 431.875 +console.log('Price in yuans: ' + price); // => Price in yuans: 431.875 ``` -Такой подход позволяет легко менять имя или форму обращения, не трогая остальной код. +Функция `String()` превращает любое значение (число, результат вычисления, булево и так далее) в строку. Подробнее про функции мы поговорим в будущих уроках. diff --git a/modules/30-variables/19-naming-style/ru/README.md b/modules/30-variables/19-naming-style/ru/README.md index 05eb59ac..24e66015 100644 --- a/modules/30-variables/19-naming-style/ru/README.md +++ b/modules/30-variables/19-naming-style/ru/README.md @@ -1,33 +1,38 @@ -Существуют несколько популярных стилей написания составных имён переменных. +`greeting` служит примером простого и понятного имени переменной. Но часто имён вроде `name`, `email` или `price` оказывается недостаточно. Например, нужно описать имя пользователя, общее количество заказов, максимальную длину сообщения. Такие имена уже состоят из нескольких слов. Как в таком случае будет выглядеть имя переменной? -```text -kebab-case: max-message-length -snake_case: max_message_length -CamelCase: MaxMessageLength -lowerCamelCase: maxMessageLength -``` +В разных языках программирования используются разные стили именования. От этого зависит, как будет выглядеть имя переменной из нескольких слов. Например, вот как можно записать переменную, которая хранит максимальную длину сообщения: -В JavaScript стандартом является **lowerCamelCase**: первое слово строчными буквами, каждое последующее — с заглавной. +1. `maxmessagelength` +1. `maxMessageLength` +1. `max-message-length` +1. `max_message_length` -```javascript -const firstName = 'John'; -const maxLoginAttempts = 3; -const totalOrdersCount = 42; -``` +## Основные стили -## Что не работает в JavaScript +Вот несколько популярных подходов к написанию составных имён: -- **kebab-case** (`max-message-length`) — дефис воспринимается как минус, это будет ошибкой. -- **UPPER_SNAKE_CASE** — используется только для настоящих модульных констант (редко). +- **kebab-case**: слова разделяются дефисом — `max-message-length`. -## Важно + В JavaScript не работает, так как дефис (`-`) воспринимается как оператор вычитания. -Не включайте тип данных в имя переменной. Имя должно описывать **смысл**, а не хранение: +- **snake_case**: слова разделяются подчёркиванием — `max_message_length`. Это стандарт в некоторых других языках, например в Python. -```javascript -// Плохо -const userNameString = 'Alice'; +- **CamelCase** (или UpperCamelCase): каждое слово с заглавной буквы, без разделителей — `MaxMessageLength`. В JavaScript так принято называть классы. + +- **lowerCamelCase**: то же самое, но первое слово со строчной буквы — `maxMessageLength`. + +## Как правильно в JavaScript -// Хорошо -const userName = 'Alice'; +Стандартом для переменных в JavaScript является **lowerCamelCase**: первое слово строчными буквами, каждое последующее — с заглавной. + +```javascript +const userName = 'Daenerys'; +const maxLength = 280; +const totalOrdersCount = 17; ``` + +## Как не надо + +Не стоит включать тип данных в имя переменной. Такие имена хуже читаются и быстро устаревают. Например, `userNameString` или `messagesNumber` описывают не смысл переменной, а её техническую реализацию. + +Имя должно отвечать на вопрос «что хранится?», а не «какого это типа?». Поэтому лучше писать `userName` вместо `userNameString` и `messagesCount` вместо `messagesNumber`. diff --git a/modules/30-variables/20-magic-numbers/ru/README.md b/modules/30-variables/20-magic-numbers/ru/README.md index c9ecb432..4518be0a 100644 --- a/modules/30-variables/20-magic-numbers/ru/README.md +++ b/modules/30-variables/20-magic-numbers/ru/README.md @@ -1,28 +1,38 @@ -Что означают числа `1.25` и `6.91` в следующем коде? +Рассмотрим пример программы, которая выполняет конвертацию валют: ```javascript -const euros = 1000; -const dollars = euros * 1.25; -const yuans = dollars * 6.91; +const eurosCount = 1000; +const dollarsCount = eurosCount * 1.25; // => 1250 +const rublesCount = dollarsCount * 60; // => 75000 + +console.log(rublesCount); ``` -Без контекста непонятно. Такие числа называют **магическими** — они не несут смысла сами по себе. +Технически код работает. Но с точки зрения профессиональной разработки такой код считается плохой практикой. + +## В чём проблема? + +В выражениях использованы непонятные числа: `1.25` и `60`. Что это за значения? Курс валют? Откуда они взялись? Через месяц или год вы, скорее всего, не вспомните, что именно означают эти числа. А если код откроет другой разработчик, он просто не поймёт, откуда всё берётся. Такие числа называются магическими. -## Как исправить +Магические числа (magic numbers) представляют собой числовые значения, смысл которых не ясен из кода. Обычно они используются в математических выражениях напрямую, без переменных с понятными названиями. Чтобы понять их назначение, приходится вникать в контекст или читать дополнительную документацию. Магические числа затрудняют чтение, понимание и поддержку кода. -Вынести магические числа в именованные константы. +## Как избежать магии + +Самый простой способ состоит в том, чтобы вынести такие значения в переменные с понятными именами. Тогда смысл станет очевиден: ```javascript const dollarsPerEuro = 1.25; -const yuansPerDollar = 6.91; +const rublesPerDollar = 60; + +const eurosCount = 1000; +const dollarsCount = eurosCount * dollarsPerEuro; // => 1250 +const rublesCount = dollarsCount * rublesPerDollar; // => 75000 -const euros = 1000; -const dollars = euros * dollarsPerEuro; -const yuans = dollars * yuansPerDollar; +console.log(rublesCount); ``` -Теперь код читается как текст: «перевести евро в доллары, потом в юани». +Сами числа никуда не делись, но теперь они записаны в переменные, названия которых однозначно говорят, что это. -## Правило +## Вывод -Если число встречается в коде и его смысл не очевиден из контекста — вынесите его в константу с понятным именем. +Магические числа делают код непонятным и трудным для поддержки. Чтобы избежать этой проблемы, нужно заменять такие числа переменными с осмысленными именами. Это делает код более читаемым, особенно в долгосрочной перспективе. Понятный код всегда важнее компактности, даже если программа станет чуть длиннее. diff --git a/modules/30-variables/23-constants/index.js b/modules/30-variables/23-constants/index.js index ca245080..b219c628 100644 --- a/modules/30-variables/23-constants/index.js +++ b/modules/30-variables/23-constants/index.js @@ -1,2 +1,2 @@ -const maxLoginAttempts = 3; -console.log(maxLoginAttempts); +const MAX_LOGIN_ATTEMPTS = 3; +console.log(MAX_LOGIN_ATTEMPTS); diff --git a/modules/30-variables/23-constants/ru/EXERCISE.md b/modules/30-variables/23-constants/ru/EXERCISE.md index d10c0585..c2adc1d2 100644 --- a/modules/30-variables/23-constants/ru/EXERCISE.md +++ b/modules/30-variables/23-constants/ru/EXERCISE.md @@ -1 +1 @@ -Создайте константу `maxLoginAttempts` со значением `3` и выведите её на экран. +Создайте константу `MAX_LOGIN_ATTEMPTS` со значением `3` и выведите её на экран. diff --git a/modules/30-variables/23-constants/ru/README.md b/modules/30-variables/23-constants/ru/README.md index d028ef14..1bc23eea 100644 --- a/modules/30-variables/23-constants/ru/README.md +++ b/modules/30-variables/23-constants/ru/README.md @@ -1,15 +1,23 @@ -Некоторые значения не меняются никогда: число π, фиксированный курс валют, лимит попыток входа. Такие значения называют **константами**. +Иногда в программе встречаются значения, которые никогда не должны меняться. Например: -## const в JavaScript +- математическая константа π (пи); +- курс доллара на определённую дату; +- фиксированная комиссия сервиса. + +Такие значения называются константами, и их принято отличать от обычных переменных, чтобы не возникало желания их менять. -В JavaScript константы объявляются через `const`. +## Пример: число π ```javascript -const dollarsPerEuro = 1.25; -const maxLoginAttempts = 3; +const PI = 3.14; +console.log(PI); // => 3.14 ``` -Попытка изменить константу вызывает ошибку. +Здесь `PI` является константой, которая хранит значение числа π. Смысл константы в том, что её значение не должно меняться в ходе работы программы. + +## const в JavaScript + +Во многих языках константа — это отдельная сущность языка, значение которой нельзя изменить. В JavaScript для этого есть ключевое слово `const`. В отличие от обычной переменной, константу, объявленную через `const`, нельзя переприсвоить: ```javascript const maxLoginAttempts = 3; @@ -19,21 +27,27 @@ maxLoginAttempts = 5; // TypeError: Assignment to constant variable. ## const vs let ```javascript -let score = 0; // будет меняться -const lives = 3; // не меняется +let score = 0; // будет меняться +const lives = 3; // не меняется ``` -Используйте `const` по умолчанию. Переходите на `let` только тогда, когда точно знаете, что значение будет переприсваиваться. - -Константы проще анализировать: увидев `const`, читатель сразу знает — значение не изменится нигде в коде. С `let` такой уверенности нет, приходится отслеживать все места, где переменная могла быть изменена. +Используйте `const` по умолчанию. Переходите на `let` только тогда, когда точно знаете, что значение будет переприсваиваться. Константы проще анализировать: увидев `const`, читатель сразу знает — значение не изменится нигде в коде. С `let` такой уверенности нет, приходится отслеживать все места, где переменная могла быть изменена. ## Соглашение об именовании -Для глобальных констант — тех, что задают фундаментальные параметры всей программы — принято использовать `UPPER_SNAKE_CASE`: +Технически любая переменная, объявленная через `const`, уже является константой. Но для глобальных констант — тех, что задают фундаментальные параметры всей программы — дополнительно принято использовать стиль `UPPER_SNAKE_CASE` (его ещё называют SCREAMING_SNAKE_CASE): + +- все буквы заглавные; +- слова разделяются символом подчёркивания `_`. ```javascript -const MAX_LOGIN_ATTEMPTS = 3; +const MAX_USERS = 100; +const DEFAULT_TIMEOUT = 30; const DEFAULT_LANGUAGE = 'ru'; ``` Это не требование языка, а сигнал читателю: такое значение не должно меняться ни при каких условиях. + +## Зачем нужны константы? + +Константы делают код понятнее и безопаснее. Они помогают сразу увидеть, какие значения в программе считаются фиксированными. Это особенно важно при работе с такими данными, как математические и физические постоянные, настройки по умолчанию или фиксированные лимиты. Использование констант снижает риск ошибок: по объявлению `const` сразу понятно, что перед нами значение, которое не следует менять. Кроме того, если значение всё же потребуется изменить (например, в настройках), достаточно поменять его в одном месте, и изменение автоматически подхватится во всей программе.