До сих пор программа выполнялась строка за строкой, как рецепт без вариантов. Но настоящий сайт постоянно принимает решения: пускать ли пользователя, хватает ли денег на балансе, какую скидку дать, какую страницу показать. Сегодня вы научитесь задавать программе вопросы «да или нет» и выбирать, что делать дальше.
Сравнивать значения операторами >, <, >=, <= и понимать разницу между == и ===
Определять, какие значения JavaScript считает «ложными» (falsy), а какие «истинными» (truthy)
Собирать условия из &&, ||, ! и знать, что они возвращают на самом деле
Писать ветвления if / else if / else, тернарный оператор и switch
Использовать GitHub Copilot как помощника и не превращаться в его «пассажира»
Собрать свой первый консольный калькулятор
Как работать с этой страницей
Весь код на тёмном фоне с кнопкой ▶ Запустить — живой. Его можно менять прямо здесь и сразу видеть результат в консоли под ним. Сломали — нажмите ↺ Сброс. Подсказки к задачам спрятаны: сначала попробуйте сами, открывайте подсказку, только если застряли. В этом уроке мы ещё не пишем функции и циклы — только переменные и условия. Данные для программ задаём переменными в начале кода: меняйте значения и смотрите, как реагирует программа.
01 Операторы сравнения
Любое решение в программе начинается с вопроса: «этот возраст больше восемнадцати?», «пароль совпал?», «хватает ли денег?». Вопрос в JavaScript задаётся оператором сравнения, а ответ всегда один из двух: true («да») или false («нет»). Это тип boolean, который вы уже знаете из урока про типы данных.
Оператор
Значение
Пример
Результат
>
больше
5 > 3
true
<
меньше
5 < 3
false
>=
больше или равно
5 >= 5
true
<=
меньше или равно
4 <= 3
false
===
строго равно
5 === 5
true
!==
строго не равно
5 !== 6
true
Сравнения возвращают true или false · Ctrl + Enter
const age = 17;
const price = 35;
const balance = 120;
console.log(age >= 18); // → false: до совершеннолетия год
console.log(balance >= price); // → true: денег хватает
console.log(balance - price); // → 85: арифметика тоже работает
console.log(age !==17); // → false
Частая ошибка: один знак «=»
Один знак = — это присваивание («положи значение в переменную»), а не сравнение. Вопрос «равно ли?» задаёт ===. Перепутать их очень легко, поэтому читайте вслух: = — «станет», === — «равно ли».
Можно редактировать · Ctrl + Enter
let score = 5;
console.log(score ===7); // → false: просто вопрос, score не меняется
score = 7; // присваивание: теперь в score лежит 7
console.log(score ===7); // → true
Сравнение строк: по алфавиту, но с оговорками
Строки сравниваются «по словарю», буква за буквой. Но компьютер сравнивает не буквы, а их внутренние номера (коды) в таблице Unicode. Поэтому есть два подвоха: заглавные буквы «меньше» строчных, а числа-строки сравниваются как текст, а не как числа.
Можно редактировать · Ctrl + Enter
console.log("Аня" < "Бахтиёр"); // → true: «А» стоит в алфавите раньше «Б»
console.log("а" < "Б"); // → false: строчная «а» в таблице после заглавной «Б»
console.log("Z" < "a"); // → true: все заглавные идут раньше строчных
console.log("10" < "9"); // → true: как текст «1» раньше «9», как в словаре
console.log(10 < 9); // → false: а вот как числа
Аналогия из жизни
Номера маршруток на остановке в Душанбе. Если читать их как числа, «9» идёт раньше «10». Но если сложить таблички в алфавитном порядке, как папки в шкафу, то «10» окажется перед «9»: сравнивается первая цифра, а она у «1» меньше. Строки в JavaScript сравниваются именно как таблички в шкафу, а числа — как числа.
Сравнение разных типов
Когда с одной стороны > или < стоит строка, а с другой число, JavaScript превращает строку в число (вы видели это в уроке про приведение типов) и только потом сравнивает.
Можно редактировать · Ctrl + Enter
console.log("10" > 9); // → true: строка "10" стала числом 10
console.log("abc" > 1); // → false: "abc" стало NaN, а любое сравнение с NaN даёт false
console.log(NaN === NaN); // → false: NaN не равно даже самому себе
console.log(null > 0); // → false
console.log(null===0); // → false
console.log(null >= 0); // → true — странность языка, к ней вернёмся в следующем разделе
Три быстрые задачи: сначала пишем сравнения сами, затем предсказываем поведение строк.
ЗАДАЧА 1.1
Билет в кино
лёгкая
Возраст зрителя задан переменной age. Выведите в консоль четыре ответа «да/нет», по одному в строке: 1) можно ли смотреть фильм 18+ (возраст от 18); 2) можно ли смотреть фильм 12+ (от 12); 3) верно ли, что зритель младше 6 лет; 4) верно ли, что возраст не равен 17.
Можно редактировать · Ctrl + Enter
const age = 17;
// четыре строки console.log с оператором сравнения в каждой
Ожидаемый результат
false
true
false
false
Подсказка 1
Внутрь console.log можно положить само сравнение: console.log(age > 5) выведет true или false.
Подсказка 2
«От 18» значит «18 и больше» — включительно, поэтому нужен оператор >=, а не >. Для четвёртого вопроса подойдёт !==.
ЗАДАЧА 1.2
Предскажите вывод: строки
лёгкая
Не запуская код, впишите в prediction результат каждого из пяти сравнений ("true" или "false"). Код сверит прогноз с настоящим. Каждое расхождение объясните себе вслух: что вы упустили?
Можно редактировать · Ctrl + Enter
// Впишите прогноз: true или false для каждого сравнения (каждое значение — текстом, как его покажет консоль)const prediction = ["", "", "", "", ""];
const actual = [
"Фарход" < "Шахром",
"яблоко" < "арбуз",
"Dushanbe" < "dushanbe",
"100" < "20",
100 < 20,
].map(String);
console.log(actual.join("|") === prediction.join("|") ? "Верно!" : "Не угадали, подумайте ещё");
Ожидаемый результат
Верно!
Подсказка 1
Строки сравниваются по первой отличающейся букве: сначала смотрим, какая из них стоит раньше в алфавите.
Подсказка 2
В четвёртой строке сравниваются тексты (кавычки!): первые символы «1» и «2», и «1» раньше. В пятой кавычек нет — это числа.
ЗАДАЧА 1.3
Хватит ли на обед
средняя
Вы с друзьями пришли в чайхону. На счёте у вас balance сомони, самбуса стоит price сомони, берёте count штук. Выведите две строки: Хватает: true (или false) и Остаток: .... Остаток считайте как баланс минус стоимость заказа.
Стоимость заказа — это price * count. Её можно написать прямо внутри сравнения: balance >= price * count. Умножение выполняется раньше сравнения.
Подсказка 2
console.log принимает несколько значений через запятую и печатает их через пробел: console.log("Хватает:", balance >= price * count).
02 Строгое и нестрогое равенство
В JavaScript два вида «равно». Они выглядят похоже, но ведут себя совершенно по-разному.
=== — строгое равенство. Сравнивает и значение, и тип. Если типы разные — сразу false, без попыток что-то преобразовать.
== — нестрогое равенство. Если типы разные, сначала пытается привести значения к общему типу, и только потом сравнивает.
Можно редактировать · Ctrl + Enter
console.log(5===5); // → true: число и число
console.log(5==="5"); // → false: число и строка, типы разные
console.log(5 == "5"); // → true: == превратило строку "5" в число и сравнило
Аналогия из жизни
Строгое === — это охранник на входе в университет: проверяет паспорт полностью — и имя, и документ. Нестрогое == — это добрый знакомый: «Ну, вы похожи на Фархода, проходите». Иногда он угадывает, но иногда пропускает не того. В коде мы хотим предсказуемости, поэтому охранник лучше.
Таблица: что происходит с ==
Нестрогое сравнение подчиняется длинному списку правил. Запоминать их все не нужно, но полезно один раз увидеть, к чему они приводят:
Всегда пишем === и !==. Единственное, что стоит запомнить про ==: умение прочитать его в чужом коде и понимание, почему оно опасно. Если нужно сравнить число из формы со строкой — преобразуйте явно: Number(input) === 5. Явное лучше неявного: код читается однозначно.
Так плохо
Работает «случайно» и ломается, когда пользователь введёт пустую строку.
Как НЕ надо
const answer = "";
if (answer == 0) {
console.log("Ответ — ноль!"); // выведется, хотя пользователь ничего не ввёл
}
Так хорошо
Тип приводится явно, пустая строка не превращается в ноль незаметно.
JavaScript
const answer = "";
if (answer !==""&&Number(answer) ===0) {
console.log("Ответ — ноль!"); // не выведется
}
Для каждого из шести сравнений впишите прогноз ("true" или "false") в prediction и только потом запустите. Строки, где вы ошиблись, запишите в конспект вместе с причиной.
Можно редактировать · Ctrl + Enter
// Впишите прогноз: true или false для каждого сравнения (каждое значение — текстом, как его покажет консоль)const prediction = ["", "", "", "", "", ""];
const actual = [
5 == "5",
5==="5",
0 == false,
null == undefined,
null===undefined,
NaN == NaN,
].map(String);
console.log(actual.join("|") === prediction.join("|") ? "Верно!" : "Не угадали, подумайте ещё");
Ожидаемый результат
Верно!
Подсказка 1
Спросите себя: одинаковые ли типы у значений? Если да — нестрогое и строгое сравнение дают один результат.
Подсказка 2
Сверьтесь с таблицей выше. Отдельно запомните два «особых» случая: null == undefined и NaN.
ЗАДАЧА 2.2
PIN-код не подходит
средняя
Банкомат хранит PIN как строку "1234", а пользователь ввёл число 1234. Код ниже сравнивает строго и поэтому не пускает пользователя. Не меняя оператор и не превращая entered в строку, исправьте программу: приведите pin к числу явно.
Строка и число — разные типы, поэтому === вернул false. Нужно сравнивать значения одного типа.
Подсказка 2
Функция Number("1234") возвращает число 1234. Оберните ею pin прямо в условии: Number(pin) === entered.
ЗАДАЧА 2.3
Охота на странности
сложная
Восемь выражений, из которых как минимум три вас удивят. Впишите прогнозы в prediction ("true" или "false") и запустите. Затем для тех строк, где ошиблись, допишите в коде рядом комментарий в одну строку: какое правило сработало.
Можно редактировать · Ctrl + Enter
// Впишите прогноз: true или false для каждого выражения (каждое значение — текстом, как его покажет консоль)const prediction = ["", "", "", "", "", "", "", ""];
const actual = [
"" == 0,
"0" == false,
null == 0,
null >= 0,
undefined == null,
undefined == 0,
"1" == 1.0,
"abc" == NaN,
].map(String);
console.log(actual.join("|") === prediction.join("|") ? "Верно!" : "Не угадали, подумайте ещё");
Ожидаемый результат
Верно!
Подсказка 1
При == строки и булевы значения превращаются в числа. А вот null и undefined подчиняются отдельному правилу.
Подсказка 2
Четвёртая строка использует >=, а не ==. Операторы <, >, <=, >= приводят null к 0, поэтому 0 >= 0 даёт true.
03 Истинные и ложные значения (truthy / falsy)
Условие не обязано быть сравнением. В if можно положить любое значение, и JavaScript сам превратит его в true или false. Это то самое неявное приведение к boolean, о котором шла речь в уроке про типы.
Всего восемь «ложных» значений, остальное — истина
Значения, которые превращаются в false, называют falsy («ложноватые»). Запомните основные пять — они встречаются каждый день:
Falsy значение
Что это
false
само ложное значение
0 (а также -0, 0n)
число ноль
""
пустая строка
null
«намеренно пусто»
undefined
«значение не задано»
NaN
«не число»
Всё остальное — truthy («истинное»): любое ненулевое число (включая отрицательные), любая непустая строка, включая "0" и "false". Проверить любое значение можно через Boolean(...) или двойное отрицание !!:
Можно редактировать · Ctrl + Enter
console.log(Boolean(0)); // → false
console.log(Boolean("")); // → false
console.log(Boolean(null)); // → false
console.log(Boolean(NaN)); // → false
console.log(Boolean(1)); // → true
console.log(Boolean(-5)); // → true: отрицательное число — тоже истина
console.log(Boolean("Мадина")); // → true
console.log(Boolean(" ")); // → true: пробел — это символ, строка не пустая!
console.log(Boolean("0")); // → true: строка "0" не пустая
console.log(Boolean("false")); // → true: строка с текстом false — просто текст
Аналогия из жизни
Пустой стакан, пустой кошелёк, пустое место на остановке — это «нет». А кошелёк, в котором лежит одна монета, — уже «есть», пусть и немного. Но обратите внимание на одну странность: 0 — это «пусто», а строка "0" — «есть», ведь в ней лежит символ-цифра.
Как это используется
Самая частая причина смотреть на truthy/falsy — проверка «задал ли пользователь значение вообще»:
Проверка if (value) считает ложью и «не задано», и настоящий 0. Если ноль для вас допустим (скидка 0%, баланс 0 сомони, оценка 0), проверка if (discount) сработает неверно.
Впишите в prediction результат Boolean(…) для каждой из восьми строк ("true" или "false") и запустите. Особое внимание — на значениях 4, 6 и 8.
Можно редактировать · Ctrl + Enter
// Впишите прогноз: true или false для каждого значения (каждое значение — текстом, как его покажет консоль)const prediction = ["", "", "", "", "", "", "", ""];
const actual = [
Boolean(0),
Boolean("0"),
Boolean(""),
Boolean(" "),
Boolean(null),
Boolean("false"),
Boolean(-1),
Boolean(undefined),
].map(String);
console.log(actual.join("|") === prediction.join("|") ? "Верно!" : "Не угадали, подумайте ещё");
Ожидаемый результат
Верно!
Подсказка 1
Ложных значений мало: false, 0, "", null, undefined, NaN. Всё, чего нет в этом списке, — истина.
Подсказка 2
Строка с пробелом " " и строка "false" не пустые, а значит истинные: JavaScript смотрит на длину строки, а не на её смысл.
ЗАДАЧА 3.2
Привет, гость
средняя
Для каждой из трёх переменных выведите приветствие: если значение задано (truthy) — Привет, имя!, иначе — Привет, гость!. Используйте if / else без сравнений, прямо с самой переменной.
Можно редактировать · Ctrl + Enter
const name1 = "Мадина";
const name2 = "";
let name3; // значение не задано// для каждой переменной своя конструкция if / else
Ожидаемый результат
Привет, Мадина!
Привет, гость!
Привет, гость!
Подсказка 1
В скобки if можно положить саму переменную: if (name1) { ... } else { ... }.
Подсказка 2
Пустая строка и undefined — оба falsy, поэтому для второго и третьего имени сработает ветка else. Для приветствия удобна шаблонная строка: `Привет, ${name1}!`.
ЗАДАЧА 3.3
Скидка в ноль процентов
средняя
Магазин пишет «Скидки нет», когда скидка не задана, но «Скидка: 0%» и «Скидка: 15%», когда задана (даже если нулевая). Сейчас программа ошибается на нуле. Найдите баг и исправьте условие, не меняя значение discount.
Ноль — falsy, поэтому if (discount) отправляет программу в else. Нам нужно проверить не «истинность», а «задано ли значение».
Подсказка 2
Сравните с undefined строго: if (discount !== undefined). Попробуйте также заменить 0 на undefined и убедиться, что вывод станет «Скидки нет».
04 Логические операторы: &&, ||, !
Одного вопроса часто мало. «Можно в клуб, если вам 18 или больше и у вас есть паспорт». Чтобы объединять вопросы, используют три логических оператора:
&& — «и»
Истина, только если оба условия истинны.
|| — «или»
Истина, если хотя бы одно из условий истинно.
! — «не»
Переворачивает значение: !true — это false, и наоборот.
a
b
a && b
a || b
!a
true
true
true
true
false
true
false
false
true
false
false
true
false
true
true
false
false
false
false
true
Можно редактировать · Ctrl + Enter
const age = 20;
const hasTicket = true;
console.log(age >= 18&& hasTicket); // → true: оба условия выполнены
console.log(age < 18|| hasTicket); // → true: достаточно билета
console.log(!hasTicket); // → false
console.log(age >= 18&& !hasTicket); // → false
Аналогия из жизни
Чтобы подняться на канатную дорогу, нужен билет и хорошая погода (&&). Попасть в чойхону можно или через главный вход, или через дворик (||). Знак «не» — это табличка «Не работает»: она переворачивает ответ.
Приоритет и скобки
Порядок выполнения такой же, как в математике: сначала !, затем &&, потом ||. Как умножение идёт раньше сложения, так «и» идёт раньше «или». Чтобы не гадать и не путать читателя, в сложных условиях ставьте скобки.
Можно редактировать · Ctrl + Enter
const isStudent = true;
const hasCard = false;
const isWeekend = false;
// без скобок: сначала &&, потом ||
console.log(isStudent || hasCard && isWeekend); // → true// со скобками: порядок меняется
console.log((isStudent || hasCard) && isWeekend); // → false
Закон «не» (законы де Моргана)
Условие «не (А или Б)» означает то же самое, что «не А и не Б». И наоборот: «не (А и Б)» — это «не А или не Б». Это помогает упрощать запутанные условия.
Можно редактировать · Ctrl + Enter
const isClosed = false;
const isFull = true;
// «Можно войти, если НЕ (закрыто ИЛИ мест нет)»
console.log(!(isClosed || isFull)); // → false// то же самое: «НЕ закрыто И НЕ заполнено»
console.log(!isClosed && !isFull); // → false
Короткое замыкание и возвращаемые значения
Здесь начинается самое интересное. Операторы && и || на самом деле возвращают не true / false, а одно из значений, которые сравнивают. И делают это «лениво», слева направо, останавливаясь как только ответ понятен. Это называется короткое замыкание.
a || b — берёт первое истинное значение. Если истинных нет — вернёт последнее.
a && b — берёт первое ложное значение. Если ложных нет — вернёт последнее.
Можно редактировать · Ctrl + Enter
console.log(0||10); // → 10: 0 ложь, идём дальше
console.log("Алиша"||"гость"); // → Алиша: первое значение уже истинное, дальше не смотрим
console.log(null||undefined||"запасной"); // → запасной
console.log(1&&2&&3); // → 3: все истинны, вернули последнее
console.log(1&&0&&3); // → 0: остановились на первом ложном
console.log(null&&"не дойдём"); // → null
Аналогия из жизни
|| — это проверка запасных вариантов: «пойдём в чойхону у дома, а если закрыто — в соседнюю, а если и она закрыта — домой». Берём первый вариант, который сработал. && — это цепочка проверок в аэропорту: паспорт, билет, багаж. Как только одна проверка не пройдена — дальше не пускают, и мы знаем, на чём остановились.
Этим пользуются на практике. Значение по умолчанию:
Можно редактировать · Ctrl + Enter
const nickname = ""; // пользователь ничего не ввёлconst shown = nickname ||"Гость"; // если пусто — подставляем «Гость»
console.log("Привет,", shown); // → Привет, Гость
И безопасное «сделай только если»: правая часть && вычисляется лишь тогда, когда левая истинна.
Можно редактировать · Ctrl + Enter
const isAdmin = true;
isAdmin && console.log("Открываем панель администратора"); // выполнитсяconst isGuest = false;
isGuest && console.log("Это сообщение не появится"); // правая часть даже не вычислялась
Оператор ?? — «если пусто» только для null и undefined
У || есть недостаток, который вы уже видели: он считает ложью 0 и пустую строку. Для значений по умолчанию это часто неудобно: громкость 0 — это честная настройка, а не «значение не задано». Оператор ?? («нулевое слияние») подставляет запасное значение только если слева null или undefined.
Можно редактировать · Ctrl + Enter
const volume = 0; // пользователь выключил звук
console.log(volume ||50); // → 50 ✖ выключенный звук включился сам
console.log(volume ??50); // → 0 ✔ ноль сохранёнlet theme; // настройка не задана (undefined)
console.log(theme ??"светлая"); // → светлая
Значение слева
x || "запас"
x ?? "запас"
"Мадина"
Мадина
Мадина
0
запас
0
"" (пустая строка)
запас
(пустая строка)
null или undefined
запас
запас
Правило выбора простое: нужна замена для «пусто» вообще (в том числе 0 и "") — берём ||; нужна замена только для «не задано» — берём ??.
Для входа нужно: возраст от 18 и наличие билета. Выведите в трёх строках: 1) выполнены ли оба условия; 2) выполнено ли хотя бы одно из двух: «возраст от 18» или «есть билет»; 3) верно ли, что билета нет.
Можно редактировать · Ctrl + Enter
const age = 16;
const hasTicket = true;
// три строки console.log
Ожидаемый результат
false
true
false
Подсказка 1
Первая строка: age >= 18 && hasTicket. «И» требует, чтобы выполнились оба условия.
Подсказка 2
Для «хотя бы одно» нужен оператор ||, а для «билета нет» — отрицание !hasTicket.
ЗАДАЧА 4.2
Предскажите вывод: короткое замыкание
лёгкая
Впишите в prediction результат каждой из восьми строк (текстом) и запустите. Отдельно объясните себе, почему в первых двух строках ответы разные.
Можно редактировать · Ctrl + Enter
// Впишите прогноз: результат каждого выражения по порядку (каждое значение — текстом, как его покажет консоль)const prediction = ["", "", "", "", "", "", "", ""];
const actual = [
0||10,
0??10,
"Алиша"||"гость",
null&&"текст",
1&&2&&3,
1&&0&&3,
null||undefined||"последний",
null??"пусто",
].map(String);
console.log(actual.join("|") === prediction.join("|") ? "Верно!" : "Не угадали, подумайте ещё");
Ожидаемый результат
Верно!
Подсказка 1
|| возвращает первое истинное значение, && — первое ложное. Если подходящего нет, возвращается последнее значение цепочки.
Подсказка 2
0 ?? 10: слева не null и не undefined, значит ?? оставляет левую часть — ноль.
ЗАДАЧА 4.3
Билет в музей
средняя
В музее правила такие: бесплатно — дети до 7 лет (не включая 7) или люди от 65 лет. Скидка — студентам или тем, кому меньше 18. Для двух посетителей выведите по строке в формате А: бесплатно: true, скидка: false (значения подставьте через шаблонную строку).
Можно редактировать · Ctrl + Enter
const ageA = 70;
const studentA = false;
const ageB = 16;
const studentB = true;
// две строки с шаблонными строками и логическими выражениями
Внутри ${ } можно писать любое выражение, в том числе ageA < 7 || ageA >= 65.
Подсказка 2
Для скидки: studentA || ageA < 18. Результат || здесь — булево значение, потому что слева стоит булева переменная, а справа сравнение.
ЗАДАЧА 4.4
Настройки профиля
средняя
Пользователь не заполнил часть настроек. Напишите три строки с подстановкой значений по умолчанию, выбрав правильный оператор в каждой: громкость 0 нужно сохранить; пустой ник нужно заменить на Гость; не заданную тему — на светлая.
Если вариантов больше двух, между if и else добавляют сколько угодно else if. Условия проверяются сверху вниз, до первого истинного; остальные уже не проверяются.
Светофор на проспекте Рудаки. Водитель проверяет по порядку: красный? — стоим. Нет? Жёлтый? — готовимся. Нет? Значит, зелёный — едем. Как только один пункт подошёл, остальные водитель уже не рассматривает. Так работает цепочка if / else if / else.
Порядок условий важен
Раз выполняется только первая подходящая ветка, условия нужно ставить от самых строгих к самым мягким. Если поставить score >= 56 первым, то и 90 баллов получит оценку «3» — ведь 90 тоже больше 56.
Баг: неправильный порядок · Ctrl + Enter
const score = 90;
if (score >= 56) {
console.log("Оценка: 3"); // сработает уже здесь
} elseif (score >= 71) {
console.log("Оценка: 4"); // никогда не дойдём
} elseif (score >= 86) {
console.log("Оценка: 5"); // и сюда тоже
}
Составные условия и вложенность
Внутри условия можно использовать &&, || и !. А внутрь блока — класть другие if. Но много уровней вложенности трудно читать: чаще проще объединить условия через &&.
Если в блоке всего одна строка, скобки можно не писать, но делать так не стоит: при добавлении второй строки легко забыть скобки и получить ошибку. Всегда пишите { }. Кроме того, сложные проверки удобнее ставить «снизу вверх»: сначала самый исключительный случай (score > 100, «некорректный ввод»), а затем обычные.
Переменная color хранит цвет светофора. Напишите цепочку if / else if / else: "red" → Стоп, "yellow" → Приготовьтесь, "green" → Идите, любое другое значение → Светофор сломан. Проверьте программу на всех четырёх вариантах, меняя color. В итоговом коде оставьте "yellow".
Можно редактировать · Ctrl + Enter
const color = "yellow";
// цепочка if / else if / else
Ожидаемый результат
Приготовьтесь
Подсказка 1
Каждое условие — строгое сравнение строки: color === "red".
Подсказка 2
Структура: if (...) { ... } else if (...) { ... } else if (...) { ... } else { ... }. Последний else — «для всего остального».
ЗАДАЧА 5.2
Чётное или нечётное
лёгкая
Число задано переменной n. Выведите строку вида 17 — нечётное или 18 — чётное. Подсказка про оператор из прошлого урока: остаток от деления на 2 у чётных чисел равен нулю.
Можно редактировать · Ctrl + Enter
const n = 17;
// if (...) { ... } else { ... }
Ожидаемый результат
17 — нечётное
Подсказка 1
Остаток от деления даёт оператор %: n % 2 — это 0 для чётных и 1 для нечётных.
Интернет-магазин даёт скидку по сумме заказа total: до 100 сомони — без скидки; от 100 до 299 — 5%; от 300 до 499 — 10%; от 500 — 15%. Выведите две строки: Скидка: 10% и К оплате: .... Размер скидки храните в переменной discount (процент), а итог считайте от неё.
Можно редактировать · Ctrl + Enter
const total = 480;
let discount = 0;
// определите discount через if / else if// console.log("Скидка: " + discount + "%");// console.log("К оплате: " + ...);
Ожидаемый результат
Скидка: 10%
К оплате: 432
Подсказка 1
Проверяйте от большего порога к меньшему: сначала total >= 500, затем >= 300, затем >= 100. Переменная discount уже объявлена через let, поэтому в ветках ей можно присвоить новое значение.
Подсказка 2
К оплате: total - total * discount / 100. При total = 480 и discount = 10 получается 432.
ЗАДАЧА 5.4
Найдите баг: оценка 90 баллов
средняя
Студент набрал 90 баллов и должен получить «5», но программа выводит другое. Найдите причину и исправьте только порядок проверок.
Сработает первое истинное условие. Какое из условий подходит для 90? Подходят сразу три, а выполнится только верхнее.
Подсказка 2
Расставьте проверки от самого строгого порога к самому мягкому: >= 86, >= 71, >= 56, а затем else.
ЗАДАЧА 5.5
Какой треугольник
сложная
Даны три стороны a, b, c. Сначала проверьте, существует ли такой треугольник: сумма любых двух сторон должна быть строго больше третьей. Если не существует — выведите Такого треугольника нет и остановитесь. Если существует — выведите Треугольник существует и второй строкой его тип: Равносторонний (все стороны равны), Равнобедренный (равны ровно две) или Разносторонний. Проверьте программу на значениях (3, 4, 5), (2, 2, 2), (1, 2, 10); в итоговом коде оставьте (5, 5, 8).
Можно редактировать · Ctrl + Enter
const a = 5;
const b = 5;
const c = 8;
// вложенный if: существует ли, затем тип
Ожидаемый результат
Треугольник существует
Равнобедренный
Подсказка 1
Существование: a + b > c && a + c > b && b + c > a. Если оно ложно — это ветка else внешнего if.
Подсказка 2
Внутри внешнего if — цепочка: сначала «все три равны» (a === b && b === c), затем «хотя бы две равны» (a === b || b === c || a === c), иначе — разносторонний. Порядок важен: равносторонний тоже подходит под «две равны».
06 Тернарный оператор ? :
Когда нужно просто выбрать одно из двух значений, конструкция if / else занимает слишком много места. Для таких случаев есть сокращённая запись — тернарный оператор. Он единственный в JavaScript с тремя частями («тернарный» значит «тройной»).
Табличка на двери чойхоны: «Открыто / Закрыто». Хозяин одним взглядом на часы выбирает, какой стороной повесить табличку. Тернарный оператор делает ровно это: по условию выбирает одно из двух готовых значений.
Где он удобен
Результат тернарного оператора — значение, поэтому его можно вставить прямо в шаблонную строку или в аргумент console.log:
Тернарный оператор нужен, чтобы получить значение. Если вам нужно выполнить разные действия (вывести одно, сохранить другое), используйте обычный if. Выражение вроде cond ? console.log("a") : console.log("b") работает, но читается плохо.
Перепишите if / else ниже в одну строку с тернарным оператором. Результат не должен измениться.
Было (только читать)
const age = 20;
let status;
if (age >= 18) {
status = "Совершеннолетний";
} else {
status = "Несовершеннолетний";
}
console.log(status);
Ваш вариант · Ctrl + Enter
const age = 20;
// ваш тернарный оператор: объявите status и положите в него результат
console.log(status);
Ожидаемый результат
Совершеннолетний
Подсказка 1
Теперь переменную можно объявить через const и сразу положить в неё результат: const status = условие ? ... : ...;
Подсказка 2
Схема: age >= 18 ? "Совершеннолетний" : "Несовершеннолетний".
ЗАДАЧА 6.2
Открыто или закрыто
средняя
Чойхона работает с 9:00 до 22:00 (22:00 уже закрыто). Для двух моментов времени hour1 и hour2 выведите по строке Чойхона: открыта или Чойхона: закрыта с помощью тернарного оператора.
Составное условие можно положить прямо перед знаком вопроса: hour1 >= 9 && hour1 < 22 ? "открыта" : "закрыта".
ЗАДАЧА 6.3
Цепочка: жарко, тепло, прохладно
сложная
Для трёх температур t1, t2, t3 с помощью цепочки тернарных операторов выберите описание: от 30 и выше — Жарко, от 15 до 29 — Тепло, ниже 15 — Прохладно. Запишите цепочку по строкам, как в примере выше. Затем честно ответьте себе: что читается легче — она или else if?
Цепочка читается слева направо: t >= 30 ? "Жарко" : t >= 15 ? "Тепло" : "Прохладно". Второй вопрос задаётся только если ответ на первый «нет».
Подсказка 2
Каждую из трёх констант считайте отдельной цепочкой: подставьте t1, t2, t3 вместо t.
07 Конструкция switch
Если нужно сравнить одну и ту же переменную со многими конкретными значениями, цепочка из десяти else if получается громоздкой. Для этого придумали switch («переключатель»).
Вычисляется выражение в скобках после switch — здесь day.
Значение сравнивается строго (как ===) с каждым case сверху вниз.
Находится первое совпадение — и код выполняется с этого места вниз.
break выходит из switch. Если break нет — выполнение продолжается дальше.
default — «ничего не подошло», аналог else. Его пишут в конце.
Аналогия из жизни
Меню в чойхоне: официант слышит «курутоб» и идёт прямо к нужной строчке меню, а не читает все блюда по порядку. default — это «такого блюда у нас нет». А если забыть break, то официант принесёт и курутоб, и всё, что записано ниже в меню.
Забыли break: «проваливание» (fall-through)
Самая известная ловушка switch. Без break JavaScript находит нужный case и выполняет всё, что ниже, пока не встретит break или конец switch.
Забыли break · Ctrl + Enter
const n = 2;
switch (n) {
case1:
console.log("Один");
case2:
console.log("Два");
case3:
console.log("Три");
default:
console.log("Неизвестно");
}
// выведет: Два, Три, Неизвестно — всё, что ниже совпавшего case
Полезное проваливание: несколько case — одно действие
Бывает и полезная сторона. Если у нескольких значений действие одинаковое, их можно записать подряд, а break поставить только после общего кода:
switch сравнивает значения как ===, без приведения типов. Поэтому число 1 и строка "1" — разные значения:
Тип не совпал · Ctrl + Enter
const choice = "1"; // строка, как из поля формыswitch (choice) {
case1:
console.log("Число один");
break;
case"1":
console.log("Строка «1»");
break;
default:
console.log("Не нашли");
}
Когда что выбирать
Инструмент
Один вопрос «да / нет»
if / else
Выбрать одно из двух значений
тернарный оператор
Диапазоны («от 71 до 85»), сложные условия
if / else if
Одна переменная сравнивается с конкретными значениями (1, 2, 3 или "+", "-")
switch
Совет
Всегда пишите default, даже если «этого не может быть». Пользователь, опечатка или данные из сети рано или поздно подкинут неожиданное значение, и вы сразу узнаете об этом по сообщению, а не по тихому сбою.
Номер дня недели хранится в day (1 — понедельник, ..., 7 — воскресенье). Напишите switch, который выводит название дня. Для любого другого значения выведите Нет такого дня. Проверьте на значениях 1, 7 и 9; в итоговом коде оставьте 5.
Можно редактировать · Ctrl + Enter
const day = 5;
// switch (day) { ... }
Ожидаемый результат
Пятница
Подсказка 1
У каждого case своё число и свой console.log, после которого обязательно стоит break.
Подсказка 2
Для семи дней нужно семь case: от case 1: до case 7:. Ветка default — в самом конце.
ЗАДАЧА 7.2
Дни недели: рабочий или выходной
средняя
Используя «полезное проваливание», сделайте так, чтобы для дней 1–5 выводилось Рабочий день, для 6 и 7 — Выходной, для остального — Некорректный номер. Не повторяйте один и тот же console.log в нескольких местах.
Можно редактировать · Ctrl + Enter
const day = 6;
// switch (day) { ... }
Ожидаемый результат
Выходной
Подсказка 1
Пять case подряд (case 1: case 2: ...), затем один общий console.log и break.
Подсказка 2
Структура: case 1: case 2: case 3: case 4: case 5: ... break;, затем case 6: case 7: ... break;, затем default.
ЗАДАЧА 7.3
Найдите баг: забытые break
средняя
Программа должна вывести название только одной марки хлеба, а выводит несколько строк. Сначала запустите и посмотрите, что выведется. Объясните себе почему, затем исправьте код.
Совпал case "tandir", и выполнение «провалилось» вниз — через "non" и default.
Подсказка 2
Добавьте break; после каждого console.log (в последней ветке он необязателен, но лучше поставить для порядка).
ЗАДАЧА 7.4
Доставка по городам
сложная
Курьерская служба называет сроки по городам. Душанбе — 1 день; Бохтар и Вахдат — 2 дня; Худжанд и Куляб — 3 дня; Хорог — 5 дней; остальные города — Уточняйте у оператора. Города с одинаковым сроком объедините. Выведите строку Доставка: .... Затем сами подумайте: что произойдёт, если в city лежит "бохтар" с маленькой буквы?
Можно редактировать · Ctrl + Enter
const city = "Бохтар";
// switch (city) { ... }
Ожидаемый результат
Доставка: 2 дня
Подсказка 1
Города с одинаковым сроком — это подряд идущие case без break между ними, а общий console.log и break — после последнего из них.
Подсказка 2
Сравнение в switch строгое и чувствительно к регистру: "бохтар" не совпадёт с "Бохтар" и попадёт в default. Это нормально для нашего урока; позже вы научитесь приводить строки к одному регистру.
08 ИИ-блок: GitHub Copilot в VS Code
ИИ-подсказка
Copilot — это не учитель, а очень быстрый и очень самоуверенный напарник. Он видит ваш код и угадывает, что вы собираетесь написать дальше. Угадывает часто верно, но иногда уверенно предлагает код с ошибкой. Наша цель на курсе — чтобы вы понимали каждую строку, которую он предложил. Поэтому сегодня учимся не только включать Copilot, но и выключать его.
Напомним правила курса: сначала пробуйте сами 15 минут, не вставляйте код, который не можете объяснить построчно, и всегда проверяйте крайние случаи руками. Copilot включаем на практике и выключаем на контрольных заданиях.
1. Как Copilot работает в редакторе
Пока вы печатаете, Copilot показывает бледный «призрачный» текст — предложение продолжить. Его можно принять целиком, по словам или отклонить. Клавиши в стандартной раскладке VS Code:
Действие
Клавиши
Принять предложение целиком
Tab
Принять только следующее слово
Ctrl (на Mac Cmd) + →
Отклонить предложение
Esc или просто продолжайте печатать своё
Следующий / предыдущий вариант
Alt (на Mac Option) + ] / [
Inline chat: задать вопрос прямо в коде
Ctrl (на Mac Cmd) + I
В inline chat вы выделяете кусок кода, нажимаете Ctrl/Cmd + I и пишете запрос обычными словами. Есть и короткие команды: /explain — объяснить код, /fix — найти ошибку, /tests — предложить тесты. Для новичка самое ценное — именно /explain и вопрос «какие крайние случаи я не учёл?».
2. Где Copilot помогает
Рутина: повторяющиеся строки, скобки, шаблонный код. Руки не устают, голова свободна для логики.
Забытый синтаксис: «как записать switch?» — быстрее, чем искать в документации.
Данные для проверки: «предложи 10 тестовых значений для проверки возраста».
Второй взгляд: «найди граничные случаи в моём условии» после того, как вы написали код сами.
3. Где Copilot мешает учиться
Условия и логика — именно та тема, где мышление важнее печатания. Мозг учится, когда напрягается: вы сами решаете, какой оператор и в каком порядке. Если вы просто нажимаете Tab, у вас появляется иллюзия понимания: код есть, а в голове пусто. На контрольной и на собеседовании вы останетесь один.
Аналогия из жизни
Копилот — как навигатор в такси. Если вы всегда ездите с навигатором, то и через год не будете знать, как проехать по Душанбе: «повернуть налево» — это не карта в голове. Зато, если сначала сами строите маршрут, а потом сверяетесь с навигатором, то запоминаете город — и находите места, где навигатор ведёт странно.
Типичная ошибка Copilot в условиях
Как это выглядит
Как поймать
Граница: > вместо >=
if (age > 18), а правило «от 18»
Проверить значения на границе: 17, 18, 19
Нестрогое ==
if (answer == 0)
Правило курса: только ===
Ноль как «пусто»
if (balance) — баланс 0 считается «нет значения»
Проверить значение 0 и пустую строку
Забытый break
Выводятся сразу несколько веток switch
Запустить для каждого case
Неправильный порядок условий
«Мягкое» условие стоит выше «строгого»
Прогнать самое большое и самое маленькое значения
Не учтён «лишний» ввод
Нет ветки default / деления на ноль
Спросить: «что будет, если ввести ерунду?»
4. Дисциплина «Copilot off»
Привычка работы, которой мы придерживаемся на курсе:
Прочитайте задачу и напишите решение словами или схемой в тетради: какие бывают случаи, в каком порядке их проверять.
Выключите Copilot и напишите код сами. Нажмите на значок Copilot в нижней строке состояния VS Code и выберите «Disable Completions» (отключить подсказки) — для всех файлов или только для JavaScript.
Запустите и проверьте на граничных значениях и на «плохих» данных.
Только потом включите Copilot как рецензента: выделите код, Ctrl/Cmd + I, «найди граничные случаи, которые я не учёл».
Сравните с вашим решением. Что он предложил такого, чего вы не знали? Запишите в конспект одну строку.
Правило
На контрольных работах (уроки 6 и 18) ИИ выключен полностью, включая Copilot. Если вы не тренировали навык без подсказок, контрольная покажет это сразу. Каждую неделю делайте часть заданий в режиме «Copilot off» — как спортсмен без шипов на тренировке.
Контекст: я учу JavaScript с нуля, 3-й урок, знаю переменные, операторы, if/else и switch. Функций и циклов ещё не знаю.
Задача: помоги составить консольный калькулятор: две переменные-числа a и b, переменная operation со знаком действия (+, -, *, /), результат выводится через console.log.
Ограничения: только switch и if, без функций, циклов и внешних библиотек; на деление на ноль и неизвестную операцию выводить сообщение об ошибке.
Формат ответа: сначала план из 4 шагов словами, потом код, потом объяснение каждой строки.
Проверка: назови 3 набора входных данных, на которых моя программа может сломаться.
Вот мой код: [вставьте код]. Я пока не знаю, правильно ли я расставил условия. Не переписывай код. Скажи, на каких значениях он ведёт себя неверно (граничные значения, ноль, пустая строка, неверный тип), и покажи эти значения списком.
Объясни построчно, как новичку, что делает этот switch: [код]. Что выведется, если убрать все break? Ответ — по шагам, на конкретном значении переменной.
Дай 5 задач на if / else и switch для новичка: от простой к сложной, про жизнь в Душанбе (маршрутки, чойхона, магазин). Без решений. Для каждой — 3 тестовых набора данных с ожидаемым выводом, чтобы я мог проверить себя.
Теперь два упражнения: Copilot-подобные «предложения», которые выглядят правдоподобно, но ошибаются. Ваша работа — поймать ошибку, как рецензент.
Практика: проверяем подсказки ИИ
ЗАДАЧА 8.1
Бесплатный проезд: граница
средняя
Правило: дети до 12 лет включительно (то есть и 12-летние тоже) ездят бесплатно. Этот код «предложил Copilot». Проверьте его на границе (11, 12, 13), найдите баг и исправьте.
Можно редактировать · Ctrl + Enter
const age = 12;
// предложение Copilot:if (age < 12) {
console.log("Бесплатно");
} else {
console.log("Платно");
}
Ожидаемый результат
Бесплатно
Подсказка 1
«До 12 включительно» означает, что 12 — тоже бесплатно. Что для 12 возвращает 12 < 12?
Подсказка 2
Замените < на <=. Затем попробуйте значения 11, 12 и 13: бесплатно, бесплатно, платно.
ЗАДАЧА 8.2
Баланс телефона: ноль не пустота
средняя
Код «от Copilot» должен сообщать: Баланс: ... сомони, если баланс известен (включая 0!), и Баланс неизвестен, если значение не задано. На нулевом балансе он ошибается. Исправьте, не меняя значение balance.
Какое значение у balance — «не задано» или «задано, равно нулю»? А как if воспринимает ноль?
Подсказка 2
Спросите именно про «задано»: if (balance !== undefined). Попробуйте также заменить 0 на undefined и убедиться, что выведется «Баланс неизвестен».
09 Практика на уроке: консольный калькулятор
Соберём первую настоящую программу. Это калькулятор: он берёт два числа и знак действия, считает и выводит ответ в консоль. Интерактивного ввода (через prompt) на этой странице нет, поэтому данные мы задаём переменными вверху: a, b и operation. Меняйте их и запускайте — так вы и тестируете программу.
План урока и режимы Copilot
Задачи 9.1–9.2 — калькулятор. Copilot включён: пользуйтесь подсказками, но каждую принятую строку объясните соседу.
Задачи 9.3–9.4 — задачи на логику. Copilot выключен (см. дисциплину в разделе 8). Только вы, тетрадь и консоль.
После — включите Copilot и попросите его проверить граничные случаи ваших решений 9.3–9.4. Запишите в конспект одну находку.
Каркас калькулятора
Данные: два числа a, b и строка operation со знаком.
Выбор действия:switch (operation) с вариантами "+", "-", "*", "/".
Результат: вывести строку вида 12 * 4 = 48.
Защита: деление на ноль — отдельная ошибка; неизвестная операция — ветка default.
Каркас: два действия из четырёх · Ctrl + Enter
const a = 12;
const b = 4;
const operation = "+";
switch (operation) {
case"+":
console.log(`${a} + ${b} = ${a + b}`);
break;
case"-":
console.log(`${a} - ${b} = ${a - b}`);
break;
// здесь будут "*" и "/"default:
console.log("Неизвестная операция");
}
Практика: собираем калькулятор
ЗАДАЧА 9.1
Калькулятор: четыре действия
средняя
Copilot включён. Допишите калькулятор: +, -, *, /. Вывод — строка вида 12 * 4 = 48. Для неизвестной операции — Неизвестная операция. Проверьте все четыре знака, меняя operation. В итоговом коде оставьте "*".
Можно редактировать · Ctrl + Enter
const a = 12;
const b = 4;
const operation = "*";
// switch (operation) { ... }
Ожидаемый результат
12 * 4 = 48
Подсказка 1
Один case на знак. Внутри каждого — console.log с шаблонной строкой и break.
Подсказка 2
Знаки — это строки, поэтому в case они в кавычках: case "*":.
ЗАДАЧА 9.2
Калькулятор: защита от ошибок
средняя
Copilot включён. Добавьте в калькулятор защиту: при делении на ноль вместо ответа выводится Ошибка: на ноль делить нельзя. Плюс две новые операции: % (остаток) и ** (степень). В итоговом коде оставьте деление 10 / 0. Проверьте также 7 % 3 (ответ 1) и 2 ** 5 (ответ 32).
Можно редактировать · Ctrl + Enter
const a = 10;
const b = 0;
const operation = "/";
// switch (operation) { ... }
Ожидаемый результат
Ошибка: на ноль делить нельзя
Подсказка 1
Внутри case "/" нужен свой if / else: если b === 0 — сообщение об ошибке, иначе — вычисление.
Подсказка 2
Остаток от деления на ноль тоже не определён (получится NaN), поэтому такую же проверку стоит добавить и в case "%".
ЗАДАЧА 9.3
Минимум из трёх (Copilot off)
средняя
Copilot выключен. Три цены на один и тот же хлеб в разных магазинах: p1, p2, p3. Выведите самую низкую цену в виде Минимум: 6. Нельзя использовать Math.min — решите условиями. Проверьте программу, когда минимальна первая, вторая, третья цена и когда есть одинаковые цены.
Можно редактировать · Ctrl + Enter
const p1 = 9;
const p2 = 6;
const p3 = 7;
// if / else if / else и &&
Ожидаемый результат
Минимум: 6
Подсказка 1
Минимум — это то число, которое не больше обоих других. Например, p1 минимальное, если p1 <= p2 && p1 <= p3.
Подсказка 2
Если не подходит p1 и не подходит p2, то минимум — p3. Это ветка else. Знак <= (а не <) нужен, чтобы при одинаковых ценах всё сработало.
ЗАДАЧА 9.4
Fizz, Buzz или FizzBuzz (Copilot off)
сложная
Copilot выключен. Классика собеседований. Для числа n выведите: FizzBuzz, если оно делится и на 3, и на 5; Fizz — если только на 3; Buzz — если только на 5; иначе само число. Проверьте значения 15, 9, 10, 7; в итоговом коде оставьте 15. Подумайте, в каком порядке нужно расставить проверки, чтобы 15 не стало просто «Fizz».
Можно редактировать · Ctrl + Enter
const n = 15;
// if / else if / else
Ожидаемый результат
FizzBuzz
Подсказка 1
Делимость проверяется остатком: n % 3 === 0. «И на 3, и на 5» — это два таких сравнения через &&.
Подсказка 2
Самое строгое условие (оба делителя) ставим первым, потом «только 3», потом «только 5», в конце else с console.log(n).
★ Домашнее задание: три консольные программы
Три программы, каждая в своём файле. Запускать их можно в консоли браузера (DevTools из первого урока) или на этой странице. Данные задавайте переменными в начале файла. Без функций и циклов: только переменные, if / else, тернарный оператор и switch.
Программа 1. Калькулятор
Развитие классной работы: a, b, operation.
☐ Операции +, -, *, /, %, ** через switch.
☐ Деление и остаток на ноль — сообщение об ошибке вместо результата.
☐ Неизвестная операция — сообщение об ошибке (default).
☐ Проверка типов: если a или b не число (typeof a !== "number"), вывести Ошибка: нужны числа и не считать.
☐ Вывод в виде 12 * 4 = 48.
Программа 2. Определитель високосного года
Год задан переменной year. Правило: год високосный, если он делится на 4, но не делится на 100, за исключением годов, которые делятся на 400.
Год
Ожидаемый ответ
Почему
2024
високосный
делится на 4, не делится на 100
2023
не високосный
не делится на 4
1900
не високосный
делится на 100, но не на 400
2000
високосный
делится на 400
2100
не високосный
делится на 100, но не на 400
☐ Вывод: 2024 — високосный год или 2023 — не високосный год.
☐ Условие записано одним составным выражением с && и || и скобками, либо цепочкой if / else if — выберите и объясните выбор.
☐ В комментарии в начале файла — таблица проверенных годов (минимум пять, все из таблицы выше).
☐ Эту программу пишите с выключенным Copilot. Включите его только в конце, для проверки граничных случаев.
Программа 3. Конвертер валют
Курсы зафиксированы в программе: 1 USD = 10.5 сомони, 1 RUB = 0.12 сомони. Заданы сумма amount, исходная валюта from и целевая to (строки "TJS", "USD", "RUB"). Идея: сначала переведите сумму в сомони («общий знаменатель»), потом из сомони в нужную валюту.
Каркас конвертера · Ctrl + Enter
const amount = 100;
const from = "USD";
const to = "TJS";
const USD_RATE = 10.5; // сколько сомони стоит 1 долларconst RUB_RATE = 0.12; // сколько сомони стоит 1 рубльlet inSomoni;
switch (from) {
case"TJS":
inSomoni = amount;
break;
case"USD":
inSomoni = amount * USD_RATE;
break;
// здесь будет "RUB"default:
console.log("Неизвестная исходная валюта");
}
console.log(inSomoni); // → 1050// дальше: второй switch (to) считает итог из inSomoni
Вход
Ожидаемый вывод
100 USD → TJS
100 USD = 1050 TJS
1050 TJS → RUB
1050 TJS = 8750 RUB
1000 RUB → TJS
1000 RUB = 120 TJS
500 TJS → USD
500 TJS = 47.62 USD (округление до 2 знаков)
200 USD → RUB
200 USD = 17500 RUB
☐ Все пары из трёх валют работают, включая USD ↔ RUB через сомони.
☐ Если from === to — вывести сумму без пересчёта.
☐ Неизвестная валюта (в любом поле) или отрицательная сумма — сообщение об ошибке.
☐ Результат округляется до 2 знаков: Math.round(x * 100) / 100.
☐ Бонус: добавьте четвёртую валюту (например, EUR) и покажите, сколько мест в коде пришлось изменить.
Что сдать
Три файла: calculator.js, leap-year.js, converter.js в папке lesson-03 репозитория GitHub (или архив в Telegram-группу).
В начале каждого файла — комментарий с тестовыми значениями: какие входные данные вы проверили и что получилось.
Файл README.md из трёх строк: в каких задачах вы использовали Copilot; что он предложил; что вы исправили или отклонили.
Будьте готовы на проверке объяснить любую строку: преподаватель может попросить.
Как оцениваем (0–10)
Критерий
Баллы
Калькулятор: все операции работают, защита от деления на ноль и неизвестной операции
3
Калькулятор: проверка типов и аккуратный вывод
1
Високосный год: правильные ответы на все пять годов из таблицы
2
Конвертер: все пары валют и правильное округление
2
Конвертер: защита от неверных данных
1
Чистый код (===, отступы, понятные имена) и тесты в комментариях
1
Подсказка по времени
Закладывайте 2 часа. Начинайте с високосного года: он короткий, но самый «логический». Если застряли — сначала 15 минут сами, потом вопрос в чат группы (с кодом и тем, что вы ожидали и что получили), потом ИИ по формуле промпта.
✓ Шпаргалка урока
Сравнение:><>=<= возвращают true / false. Один = — присваивание, а не сравнение. Строки сравниваются по таблице Unicode: «Z» меньше «a», а "10" < "9".
=== и !== — строгое сравнение (значение и тип). == приводит типы и ведёт к сюрпризам (0 == "", null == undefined). В коде пишем только ===; NaN не равно никому.
Falsy:false, 0, "", null, undefined, NaN. Всё остальное — truthy, включая "0", " ", "false". Ноль — настоящее значение: проверяйте !== undefined, когда ноль допустим.
Логика:&& — и, || — или, ! — не. Приоритет: !, потом &&, потом ||; сомневаетесь — ставьте скобки.
Короткое замыкание:|| возвращает первое истинное, && — первое ложное (или последнее значение цепочки). nick || "Гость" — значение по умолчанию. ?? заменяет только null и undefined: 0 ?? 50 даёт 0.
if / else if / else: условия проверяются сверху вниз до первого истинного, от строгих к мягким. Всегда с фигурными скобками.
Тернарный оператор:условие ? если_да : если_нет — для выбора одного из двух значений. Цепочки из двух уровней и больше лучше писать через if.
switch: строгое сравнение с case, break обязателен (иначе «проваливание» вниз), default — для всего остального. Подряд идущие case без break — одно действие на несколько значений.
Copilot:Tab — принять, Esc — отклонить, Ctrl/Cmd + I — inline chat. Помогает с рутиной и объяснением, мешает учиться, если принимать подсказки не думая. Сначала сами с выключенным Copilot, потом он как рецензент. Проверяйте границы (> и >=), ноль и забытые break.