Переменная — это имя, под которым программа хранит значение: в JavaScript её объявляют через const, если значение не будет переприсваиваться, и через let, если будет. У каждого значения есть тип: семь примитивных (number, string, boolean, undefined, null, bigint, symbol) и объекты, включая массивы. Тип проверяют оператором typeof, а значения сравнивают строгим ===, чтобы JavaScript не преобразовывал типы без спроса.
После материала вы сможете
- объявить переменные через
constиletи объяснить, когда нужно каждое - назвать семь примитивных типов JavaScript и предсказать результат
typeof, включая особые случаи с null, массивом и NaN - предсказать результат неявного преобразования типов и выбрать
===вместо== - обработать данные из формы: убрать пробелы, преобразовать строку в число и проверить результат через
Number.isNaN
Что знать заранее
Проверено на
Node.js 24 LTS (24.18.0)Microsoft Edge 155
Сверено с документацией: 11 октября 2026 г.
Содержание
Переменная — имя для значения: let и const
В первой программе мы писали const bill = 12500 и дальше использовали bill вместо числа. Это и есть переменная: имя, под которым программа запоминает значение. MDN называет переменные символическими именами для значений. Удобно представлять подписанную коробку: на крышке — имя, внутри — значение. В отличие от многих языков, в JavaScript на коробке не написан тип: одна и та же переменная let может сначала хранить число, а потом строку.
const shopName = "Крем Coffee"; // не меняется — const
let cupsSold = 0; // будет меняться — let
cupsSold = cupsSold + 3;
cupsSold += 2; // то же, что cupsSold = cupsSold + 2
console.log(shopName); // → Крем Coffee
console.log(cupsSold); // → 5
let discount; // объявили, но не присвоили
console.log(discount); // → undefinedЗнак = в программировании — не «равно», а «присвоить»: вычисли то, что справа, и положи под имя слева. Поэтому cupsSold = cupsSold + 3 читается как «возьми текущее значение, прибавь три и запиши обратно». Запись += — сокращение того же действия. Переменная, объявленная через let без значения, хранит undefined — «значение ещё не присвоено».
const запрещает присваивать новое значение. Попытка сделать это — ошибка во время выполнения:
const vatRate = 12;
vatRate = 16;
console.log(vatRate);$ node const-error.js
…\first-js\const-error.js:2
vatRate = 16;
^
TypeError: Assignment to constant variable.
at …
Node.js v24.18.0const
- Можно присвоить заново
- Нет
- Где видна переменная
- Внутри блока { } , где объявлена
- Когда использовать
- По умолчанию — для всего, что не переприсваивается
let
- Можно присвоить заново
- Да
- Где видна переменная
- Внутри блока { } , где объявлена
- Когда использовать
- Счётчики, накопители, значения, которые меняются
var
- Можно присвоить заново
- Да
- Где видна переменная
- Во всей функции, а не в блоке
- Когда использовать
- Старый способ: встречается в чужом коде, в новом не нужен
- Имя начинается с буквы,
_или$; дальше можно использовать и цифры:total2— можно,2total— нельзя. - Регистр важен:
totalиTotal— две разные переменные. - Нельзя называть переменные служебными словами языка:
let,const,if,return,classи другими. - По соглашению в JavaScript имена пишут в стиле camelCase:
cupsSold,deliveryPrice. Это не правило языка, но так написан почти весь код, который вы встретите.
Примитивы: семь простых типов
Стандарт ECMAScript определяет восемь типов данных: семь примитивных и объект. Примитив — простое неизменяемое значение: число, строка, логическое значение. «Неизменяемое» значит, что строку нельзя поправить на месте — методы строк возвращают новую строку, а исходная остаётся прежней.
number
- Пример
- 12500, 0.5, -3, NaN
- typeof
- "number"
- Для чего
- Любые числа — целые и дробные
string
- Пример
- "Алматы", 'кофе', шаблон в обратных кавычках
- typeof
- "string"
- Для чего
- Текст
boolean
- Пример
- true, false
- typeof
- "boolean"
- Для чего
- Да или нет: оплачен ли заказ, есть ли товар
undefined
- Пример
- undefined
- typeof
- "undefined"
- Для чего
- Значение не присвоено
null
- Пример
- null
- typeof
- "object"
- Для чего
- Намеренно пусто: «телефона нет»
bigint
- Пример
- 9007199254740993n
- typeof
- "bigint"
- Для чего
- Очень большие целые числа
symbol
- Пример
- Symbol("id")
- typeof
- "symbol"
- Для чего
- Уникальные ключи; новичку понадобится редко
console.log(typeof 12500); // → number
console.log(typeof 0.5); // → number
console.log(typeof "Алматы"); // → string
console.log(typeof true); // → boolean
console.log(typeof undefined); // → undefined
console.log(typeof null); // → object
console.log(typeof 9007199254740993n); // → bigint
console.log(typeof Symbol("id")); // → symbol
console.log(typeof { id: 1042 }); // → object
console.log(typeof [1, 2, 3]); // → object
console.log(Array.isArray([1, 2, 3])); // → true
console.log(typeof NaN); // → numberТри результата стоит запомнить отдельно. typeof null даёт "object" — наследие самой первой реализации JavaScript, которое так и осталось в языке; MDN советует проверять null сравнением value === null. Массив для typeof — тоже "object", а отличить его помогает Array.isArray. И NaN, «не число», формально имеет тип number: это особое числовое значение, которое получается, когда вычисление не удалось.
Объекты и массивы — ссылочные типы
Объект — набор пар «ключ — значение»: заказ с номером, суммой и статусом. Массив — упорядоченный список: позиции в чеке, телефоны клиента. И то и другое — объекты, и с ними работает важное правило: переменная хранит не сам объект, а ссылку на него. Если присвоить объект другой переменной, копии не появится — обе переменные будут указывать на одно и то же.
const order = { id: 1042, total: 13750, status: "new" };
order.status = "paid"; // const не мешает менять содержимое
console.log(order.status); // → paid
const sameOrder = order; // вторая ссылка на тот же объект
sameOrder.total = 0;
console.log(order.total); // → 0
const copy = { ...order }; // новый объект с теми же свойствами
copy.total = 9990;
console.log(order.total); // → 0
console.log(copy.total); // → 9990
console.log([1, 2] === [1, 2]); // → false
console.log(sameOrder === order); // → trueОтсюда следует и поведение const с объектами. Как поясняет MDN, const запрещает переприсваивание, а не изменение: заменить объект целиком нельзя, а поменять его свойство можно. Чтобы получить независимую копию, используют синтаксис { ...order }. Но копия получается поверхностной: вложенные объекты внутри по-прежнему общие.
Преобразование типов: == против ===
JavaScript — язык с динамической типизацией: тип переменной не объявляют заранее, а значения при необходимости преобразуются автоматически. Это удобно, пока преобразование происходит там, где вы его ждёте. Главная ловушка — плюс: если хотя бы один операнд строка, + склеивает строки. Остальные арифметические операторы, наоборот, превращают строки в числа.
// Неявное преобразование
console.log("37" + 7); // → 377
console.log("37" - 7); // → 30
console.log("5" * "2"); // → 10
// Явное преобразование
console.log(Number("12500")); // → 12500
console.log(Number(" 42 ")); // → 42
console.log(Number("12 500")); // → NaN
console.log(Number("")); // → 0
console.log(Number(true)); // → 1
console.log(parseInt("12px", 10)); // → 12
console.log(String(42) + "1"); // → 421
console.log(Boolean("")); // → false
console.log(Boolean("0")); // → trueНадёжнее преобразовывать явно: Number(значение), String(значение), Boolean(значение). Обратите внимание на две ловушки. Number("") даёт 0, а не NaN, — пустое поле формы незаметно превратится в ноль. А Number("12 500") даёт NaN: пробел внутри числа не допускается. Если строка начинается с числа и дальше идёт текст, как в "12px", поможет parseInt — MDN советует всегда передавать ему вторым аргументом основание системы счисления, 10.
console.log(0 == "0"); // → true
console.log(0 === "0"); // → false
console.log("" == 0); // → true
console.log("" === 0); // → false
console.log(null == undefined); // → true
console.log(null === undefined); // → false
console.log(1 === 1.0); // → true
console.log("Alma" === "alma"); // → false== (нестрогое равенство)
- Перед сравнением приводит значения к общему типу
- 0 == "0" и "" == 0 — true
- Правила приведения длинные и неочевидные
- Ошибки проявляются не сразу, а на редких данных
=== (строгое равенство)
- Разные типы — сразу false, без преобразований
- 0 === "0" — false
- Результат легко предсказать
- Пара для «не равно» — !==
Строки: шаблоны и полезные методы
Строку можно записать в двойных "…", одинарных '…' или обратных кавычках (клавиша Ё в английской раскладке). Обратные кавычки дают шаблонную строку: в неё подставляются значения через ${выражение}, и она может занимать несколько строк. У строки есть длина length и десятки методов; вот те, что нужны чаще всего при работе с данными из форм.
const rawName = " алия ";
const city = "Алматы";
const clientName = rawName.trim();
console.log(clientName.length); // → 4
console.log(clientName.toUpperCase()); // → АЛИЯ
console.log(clientName[0].toUpperCase() + clientName.slice(1)); // → Алия
console.log(`Клиент: ${clientName}, ${city}`); // → Клиент: алия, Алматы
console.log(`[${rawName}]`); // → [ алия ]
const phone = "+7 701 123 45 67";
console.log(phone.replaceAll(" ", "")); // → +77011234567
console.log(phone.includes("701")); // → true
console.log(phone.at(-1)); // → 7
console.log(String(7).padStart(3, "0")); // → 007trim()
- Что делает
- Убирает пробелы по краям
- Пример
- " алия ".trim() → "алия"
toUpperCase() / toLowerCase()
- Что делает
- Меняет регистр
- Пример
- "алия".toUpperCase() → "АЛИЯ"
slice(начало, конец)
- Что делает
- Вырезает часть строки
- Пример
- "Алматы".slice(0, 3) → "Алм"
includes(текст)
- Что делает
- Проверяет, есть ли подстрока
- Пример
- "+7 701…".includes("701") → true
replaceAll(что, на что)
- Что делает
- Заменяет все вхождения
- Пример
- "1 2 3".replaceAll(" ", "") → "123"
at(индекс)
- Что делает
- Символ по номеру; отрицательный — с конца
- Пример
- "кофе".at(-1) → "е"
padStart(длина, символ)
- Что делает
- Дополняет слева до нужной длины
- Пример
- "7".padStart(3, "0") → "007"
Типичные ловушки: NaN, 0.1 + 0.2, undefined
// NaN не равен даже самому себе
const qty = Number("три");
console.log(qty); // → NaN
console.log(qty === NaN); // → false
console.log(Number.isNaN(qty)); // → true
// Дробные числа хранятся в двоичном виде приблизительно
console.log(0.1 + 0.2); // → 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // → false
console.log((0.1 + 0.2).toFixed(2)); // → 0.30
// Деньги удобнее считать в целых единицах: тиын, центы
const priceTiyn = 199990; // 1999,90 ₸
const totalTiyn = priceTiyn * 3;
console.log(totalTiyn / 100); // → 5999.7
// Целые больше 2^53 − 1 теряют точность — для них BigInt
console.log(Number.MAX_SAFE_INTEGER); // → 9007199254740991
console.log(9007199254740993); // → 9007199254740992
console.log(9007199254740993n + 1n); // → 9007199254740994n
// undefined — «значения нет», обращение к несуществующему свойству
const user = { name: "Алия" };
console.log(user.phone); // → undefinedNaN— единственное значение, которое не равно самому себе, поэтомуqty === NaNвсегдаfalse. Проверяйте черезNumber.isNaN(qty).0.1 + 0.2не равно0.3: числа хранятся в двоичном формате IEEE 754, а в двоичной системе 0.1 нельзя записать точно, как 1/3 в десятичной. Это свойство формата, а не ошибка JavaScript — так же ведут себя и другие языки с этим форматом.toFixed(2)округляет для показа и возвращает строку, а не число: используйте его при выводе, а не в расчётах.- Целые числа точно хранятся только до
Number.MAX_SAFE_INTEGER(2^53 − 1). Дальше нужнаBigInt— число сnна конце; смешивать BigInt и обычные числа в арифметике нельзя — будет TypeError. undefinedвозвращается при обращении к несуществующему свойству.nullставят сами, когда хотят сказать «значения нет намеренно».
Практика: предскажите вывод
Мы научились хранить значения и предсказывать, во что они превратятся. Следующий урок — условия и циклы: программа начнёт принимать решения — например, отклонять количество NaN, — и там же разберём, какие значения JavaScript считает «ложными». Строгие типы, которые ловят ошибки ещё до запуска, даёт TypeScript — к нему вернёмся позже в траектории.
Как проверено3 · пройденосверено 11 октября 2026 г.
- запущено, работает
variables, types, references, conversion, equality, strings, pitfalls (RU и EN)
node 24.18.0: stdout построчно сверен с комментариями // → (check-arrows), файлы запущены и как .js, и как .mjs; те же файлы выполнены в Microsoft Edge 155 headless (classic script, перехват console.log) — вывод совпал
- запущено, работает
const-error.js
node 24.18.0: TypeError: Assignment to constant variable.; Edge 155: Uncaught TypeError с тем же сообщением; shellsession в статье — реальный вывод с сокращённым путём
- запущено, работает
Решения упражнений: predict, cart-fixed, normalize (+ cart-bug в описании задачи)
node 24.18.0 и Edge 155, сверка с // →
«Запущено» — код выполнен во временном проекте или контейнере, вывод в статье взят из прогона. «Частично» — проверено с заглушками вместо внешних сервисов. «Не запускалось» — нужны устройство, аккаунт или ключ; шаги сверены с официальной документацией. Файлы проверочного проекта и логи запусков сохранены в архиве InterLAB.