Булевы значения, null и undefined
Булев тип до смешного мал: всего два значения, true («да») и false («нет»), – и при этом на нём держится вся логика программ. Чаще всего булевы значения не пишут руками, а получают из сравнений: 5 > 3 – это true. Методы из урока о строках тоже отвечают да/нет: 'кот'.includes('о') – true. Подробный разбор – в уроке «Операторы сравнения».
console.log(5 > 3); // trueconsole.log(2 > 7); // false// true – методы тоже отвечают да/нетconsole.log('кот'.includes('о'));// результат сравнения можно сохранитьconst isAdult = 20 > 17;console.log(isAdult); // truetrue и false пишутся без кавычек. В кавычках 'true' и 'false' становятся обычными строками – текстом из четырёх и пяти букв, к логике отношения не имеющим.
// boolean – без кавычекconst ready = false;// string – обычная строка из пяти буквconst text = 'false';Имя булевой переменной – это вопрос
Булево значение – это ответ «да» или «нет». Но ответ бесполезен, пока неизвестен вопрос, а вопрос в коде задаёт имя переменной. Поэтому булевы переменные называют так, чтобы имя читалось вопросом: isAdult – «совершеннолетний?», hasAccess – «есть доступ?», canEdit – «может редактировать?». Тогда строка const isAdult = true читается целиком: «совершеннолетний? – да».
Отсюда и приставки: is – «является ли», has – «есть ли», can – «может ли», should – «нужно ли». Это не требование языка: const adult = true движок примет так же охотно. Это договорённость между людьми, и держится она на том, что код читают куда чаще, чем пишут.
// имя-вопрос: значение читается как ответ// совершеннолетний? – даconst isAdult = true;// есть доступ? – нетconst hasAccess = false;// может редактировать? – даconst canEdit = true;// нужно ли повторить? – нетconst shouldRetry = false;Второе, что даёт имя-вопрос, – по нему виден тип. При объявлении переменной в JavaScript её тип отдельно не указывают: тип принадлежит текущему значению, поэтому имя помогает читателю понять, что ожидается внутри. Увидев hasAccess, читатель уверен: внутри true или false. Увидев access – не знает ничего: там может оказаться строка 'admin', число или объект.
// имя-вопрос: тип виден без чтения остального кода// точно true или falseconst hasAccess = false;// имя-существительное: что внутри – приходится гадать// булево? строка? уровень доступа числом?const access = 'admin';И отдельно – про отрицание в имени. isNotReady выглядит безобидно, пока не дойдёт до чтения: «не готов? – нет» – на такой фразе спотыкаешься даже в своём коде, а в чужом тем более. Задавайте вопрос в положительной форме: isReady.
// «не готов? – нет»: так это готов или нет?const isNotReady = false;// «готов? – да»: читается сразуconst isReady = true;Как называть булевы переменные
- Имя-вопрос с приставкой
is,has,can,shouldisAdult, hasAccess - Существительное: признак это или сама сущность – не разобрать
adult, access - Отрицание в имени: ответ придётся читать двойным отрицанием
isNotReady - Имя ни о чём: вопрос по нему не восстановить
flag, status, check - Язык примет любое имя – приставки нужны читателю, а не движку
null обычно используют как явную метку: значение намеренно отсутствует, сброшено или пока не найдено. Например, let winner = null – победитель пока не определён, и это осмысленное состояние игры. Готовые функции тоже отвечают null: поиск, который ничего не нашёл, возвращает именно его.
undefined обычно появляется, когда значение ещё не было задано: переменную объявили без начального значения или спросили у объекта несуществующее свойство (с объектами познакомимся в уроке «Массив и объект: первое знакомство»). Встретили его в выводе – чаще всего это сигнал: «что-то забыли заполнить».
// пусто по задумке: победителя пока нетlet winner = null;console.log(winner); // null// объявили, но ничего не положилиlet score;// undefined – появился самconsole.log(score);undefined не присваивают руками
Записать undefined в переменную самому язык не мешает: let cart = undefined – рабочая строка. Но так обычно не пишут, и причина не в стиле. Пока undefined появляется только сам по себе, смысл у него надёжный: «значение сюда ещё не задавали».
Присвоив undefined руками, вы это различие стираете. Теперь undefined в переменной значит либо «значение не задавали», либо «программист намеренно очистил» – и по самому значению эти случаи уже не разделить. А для намеренной пустоты есть null.
По принятой договорённости намеренное отсутствие чаще обозначают null, а undefined обычно оставляют языку и API. Это не запрет языка, а способ сохранить понятный смысл.
// пусто намеренно – решение человекаlet winner = null;// а это пустота языка: значение не задавалиlet score;console.log(winner);console.log(score);// undefined записали рукамиlet cart = undefined;// а сюда он попал самlet score;console.log(cart);console.log(score);// теперь вы знаете
- boolean – два значения: true и false, ответы на да/нет-вопросы
- Имя булевой переменной – вопрос: isAdult, hasAccess, canEdit
- null – отсутствие задано намеренно, undefined – значение ещё не определено
- Намеренное отсутствие чаще обозначают null; undefined обычно оставляют языку и API
- Сравнения и логика возвращают именно boolean
- typeof null – 'object': историческая особенность, а не объект
Что выведет console.log(10 > 100)?
Какой тип у значения 'false'?
Что вернёт typeof null?
Что выведет код: let city; console.log(city)?