Переменные: let и const
В прошлой главе программа вычисляла 2 + 3 и тут же забывала результат. Настоящим программам нужно запоминать: имя пользователя, цену товара, счёт игры. Для этого существуют переменные – именованные «коробки», в которые кладут значение, чтобы обращаться к нему по имени.
Переменную создают словом let или const, дальше идёт имя, знак = и значение. Знак = здесь – не «равно» из математики, а оператор присваивания: возьми то, что справа, и сохрани под именем слева.
Целиком запись выглядит так: let price = 100;. Здесь let price – объявление переменной, а 100 – её начальное значение. Создание переменной сразу с первым значением называют инициализацией – термин будет постоянно встречаться дальше, так что стоит привыкнуть к нему уже сейчас.
let price = 100;console.log(price); // 100// 200 – имя работает как само значениеconsole.log(price * 2);let: значение можно заменить
Переменная, созданная через let, – коробка с крышкой: значение можно достать и положить новое. Для замены знак = используется без let – переменная уже существует, мы лишь кладём в неё другое значение. После присваивания имя score связано уже с новым значением – получить прежнее через score больше нельзя.
let score = 0;console.log(score); // 0// заменяем значение: let уже не пишемscore = 10;console.log(score); // 10Важная особенность JavaScript: коробке всё равно, что в ней лежит. В одну и ту же переменную можно положить число, потом строку, потом что-нибудь ещё – язык не закрепляет за переменной тип содержимого. В некоторых других языках так нельзя: там коробка «для чисел» принимает только числа. В JavaScript тип живёт у значения, а не у коробки.
Свобода удобная, но с обратной стороной: раз язык не следит за содержимым, следить придётся вам. Хорошая привычка – не складывать в одну переменную то число, то строку без причины: читателю кода будет трудно угадать, что там сейчас.
// сейчас в коробке числоlet box = 42;// теперь строка – язык не возражаетbox = 'сорок два';box = 3.14; // и снова число// коробка объявлена «для целых чисел»int box = 42;// ошибка компиляции: строку в int не положитьbox = "сорок два";// тоже ошибка: дробное в целую коробку не лезетbox = 3.14;const: переменную нельзя переназначить
const создаёт переменную, которой нельзя присвоить другое значение. Для чисел и строк это выглядит как запечатанная коробка: после создания заменить содержимое нельзя. Попытка присвоить такой переменной новое значение вызовет ошибку выполнения TypeError: Assignment to constant variable. Звучит как ограничение, а на деле – защита: читая const, вы твёрдо знаете, что значение не подменится где-то ниже по коду.
const pi = 3.14;// 3.14 – читать можно сколько угодноconsole.log(pi);// TypeError: Assignment to constant variablepi = 3.1415;Ещё одно отличие: const нужно сразу дать значение. Запись const pi; недопустима – раз переменную нельзя переназначить позднее, она должна быть инициализирована при объявлении.
// SyntaxError: Missing initializer in const declarationconst empty;// правильно: значение сразу при объявленииconst limit = 10;По умолчанию выбирайте const. Если по смыслу программы переменная должна получать новые значения – например, это счётчик или текущий результат, – используйте let. В современном коде const обычно используется заметно чаще, чем let.
Константы в ВЕРХНЕМ_РЕГИСТРЕ
Отдельный обычай сложился для значений, которые известны до запуска программы и не меняются со временем: цвета интерфейса, адреса серверов, настройки, лимиты. Такие константы принято называть в ВЕРХНЕМ_РЕГИСТРЕ с подчёркиваниями между словами: MAX_ATTEMPTS, COLOR_ACCENT. Имя издалека сообщает: это справочное значение, «зашитое» в код.
// известно до запуска и одинаково всегда – ВЕРХНИЙ_РЕГИСТР:const MAX_ATTEMPTS = 3;const COLOR_ACCENT = '#2ec27e';const API_URL = 'https://api.example.com';// значение появляется во время работы – обычный camelCase:// например, пришло из поля вводаconst userName = 'Ира';// например, посчитана из корзиныconst totalPrice = 1_250;Правило выбора регистра такое. ВЕРХНИЙ_РЕГИСТР – когда значение известно заранее и одинаково при каждом запуске: конфигурация, цвета, лимиты. Обычный camelCase – когда значение появляется во время работы программы: оно тоже не переназначается, но до запуска неизвестно.
Главное правило – от людей, а не от языка: имя должно говорить, что внутри. price лучше, чем p, а daysUntilDeadline лучше, чем d. Код читают в десятки раз чаще, чем пишут – через неделю вы скажете себе спасибо.
Составные имена в JavaScript пишут «верблюдом» – camelCase: первое слово с маленькой буквы, каждое следующее начинается с большой: userName, totalPrice, isReady.
Кроме этого, у самого языка есть несколько формальных ограничений на имя переменной:
Что язык разрешает в имени, а что – нет
- Буквы, цифры,
_и$total_sum, price2 - Начинаться с цифры нельзя
2fast - Зарезервированные слова языка занять нельзя
const let = 5 - Регистр важен:
priceиPrice– разные переменные
// теперь вы знаете
- Переменная – имя, связанное со значением; объявление сразу с первым значением – инициализация
- let позволяет присваивать имени новые значения
- const запрещает переназначение и требует начального значения
- Правая часть присваивания вычисляется первой, затем результат записывается в имя
- Имя должно говорить, что внутри: допустимое – не значит хорошее
Что выведет этот код?
let score = 5;console.log(score + score);
Что выведет последняя строка?
let x = 7;x = x + 2;console.log(x);
Этот код выполнится без ошибки?
const pi = 3.14;pi = 3.1416;