if и else
До сих пор программа шла сверху вниз и выполняла всё подряд. Настоящая программа так себя не ведёт: она смотрит на данные и решает, что делать дальше. Инструмент для этого один и называется if — «если».
const возраст = 20;
if (возраст >= 18) {
console.log("Проходите");
}Проходите
Читается это дословно: если возраст больше или равен 18, напечатай «Проходите». Поменяйте 20 на 15 — и программа не напечатает ничего: строка внутри фигурных скобок просто не выполнится.
В круглых скобках стоит то, что даёт true или false. Это ровно те сравнения из прошлого урока: >=, ===, &&. Ничего нового учить не нужно — условие и есть сравнение, поставленное в скобки после if.
В фигурных скобках — то, что выполнится, когда условие истинно. Строк там может быть сколько угодно.
Вторая половина развилки — else, «иначе»:
const возраст = 15;
if (возраст >= 18) {
console.log("Проходите");
} else {
console.log("Нельзя");
}Нельзя
Выполнится ровно одна из двух веток, никогда обе. Это и есть развилка: дорога расходится, программа выбирает одну и идёт дальше по общему пути.
Цепочка проверок
Дорог бывает больше двух. Тогда ветки выстраивают в цепочку: else if.
const балл = 74;
if (балл >= 90) {
console.log("отлично");
} else if (балл >= 70) {
console.log("хорошо");
} else if (балл >= 50) {
console.log("зачёт");
} else {
console.log("не сдал");
}хорошо
Здесь важна одна вещь, из-за которой цепочки ломаются чаще всего. Проверки идут сверху вниз, и срабатывает первая подошедшая. Как только ветка выполнилась, остальные пропускаются — даже если их условия тоже истинны.
Балл 95 подходит и под >= 90, и под >= 70, и под >= 50. Напечатается «отлично», потому что эта проверка стоит первой. А теперь переставьте ветки наоборот, начав с >= 50, — и все, кто сдал, получат «зачёт», включая отличников.
Последний else необязателен, но обычно нужен: он ловит всё, что не подошло ни под одну проверку. Цепочка без него молча ничего не делает в неучтённом случае, а это худший вид поломки — она не падает и не пишет ошибку.
Правдивое и ложное
В скобках после if может стоять не только сравнение, но и любое значение. Тогда язык сам решает, считать его истиной или ложью.
if ("привет") console.log("строка — истина");
if (0) console.log("это не напечатается");
if ([]) console.log("пустой массив — тоже истина");строка — истина пустой массив — тоже истина
Ложными считаются ровно шесть значений, и список стоит запомнить целиком — он короткий и больше не пополняется:
false
0
"" пустая строка
null
undefined
NaN
Всё остальное — истина. Строка «false», число −1, ноль в кавычках, пустой массив, пустой объект — всё это в условии ведёт себя как правда.
Зачем это нужно. Самая частая проверка в живом коде — «значение вообще есть?»:
const имя = "";
if (имя) {
console.log("Здравствуйте, " + имя);
} else {
console.log("Здравствуйте!");
}Здравствуйте!
Одна проверка закрывает сразу три случая: имени нет (undefined), имя пустое, имя не пришло (null). Писать три сравнения не нужно.
Короткие формы
Развилка часто нужна не для того, чтобы сделать разное, а чтобы выбрать одно из двух значений. Для этого есть короткая запись — тернарный оператор.
const возраст = 20;
const статус = возраст >= 18 ? "взрослый" : "ребёнок";
console.log(статус);взрослый
Читается как вопрос: возраст больше 18? тогда «взрослый», иначе «ребёнок». Знак ? отделяет условие, : — две ветки.
Тернарный оператор возвращает значение, а if — нет. Поэтому его можно положить в переменную, передать в функцию, вставить в строку — а if нельзя.
const n = 1;
console.log(`${n} ${n === 1 ? "товар" : "товара"}`);1 товар
Вторая короткая форма — switch. Она нужна, когда одно значение сравнивают с несколькими вариантами:
const день = "сб";
switch (день) {
case "сб":
case "вс":
console.log("выходной");
break;
default:
console.log("рабочий");
}выходной
Каждая ветка заканчивается break, иначе выполнение продолжится в следующую — и это не ошибка языка, а его задумка: два case подряд без break, как в примере выше, означают «или то, или это». Забытый break в остальных случаях — ошибка, и очень тихая.