Такой простой Boolean
Эта статья для студентов базового курса по javascript в HTML Academy.
У boolean — логического типа — есть только два значения: true и false. Он настолько прост, что иногда новички его не замечают. Разберёмся, как найти все булеаны и использовать их по полной.
Уберите лишние if
Рассмотрим простую задачу: если оценка меньше трёх, будем грустить, иначе не будем.
if (mark < 3) {
sad = true;
} else {
sad = false;
}
Думаю, вслух вы прочитаете это так: «Если mark меньше 3, запишем true в sad, иначе запишем туда false». Звучит естественно. Но что у нас в условии? Что бывает в ифах? Какое-то логическое выражение. Если оно истинно, выполняется первая ветка (sad = true), а если ложно, то вторая (sad = false). То есть, mark < 3 может быть true или false. Давайте посмотрим:
console.log(5 < 3); // false
console.log(2 < 3); // true
console.log(3 < 3); // false
Ничего удивительного. Думаю, вы ожидали этого. Выходит, если mark < 3 === true, мы записываем в переменную true. А если mark < 3 === false, мы записываем в неё false. Получается, в обоих случаях мы записываем в переменную то значение, которое возвращает mark < 3. Давайте так и запишем:
sad = mark < 3;
Одна строка вместо пяти. Если вы не уверены, что этот код делает то же, что с условием, — проверьте.
Иногда в условии вы используете не булевое выражение, а нечто, что неявно к нему приводится. Например:
// str — некоторая строка
if (str) {
flag = true;
} else {
flag = false;
}
Если строка не пустая, то условие истинно, иначе ложно. Если мы запишем flag = str, то flag получится не логический, а строковый. Это не то, что нужно. Тогда нужно просто явно привести строку к логическому типу:
flag = Boolean(str);
Тогда, если строка пустая, flag станет false, во всех остальных случаях — true.
Этот подход хорошо работает с элементами форм. У них есть булевые свойства типа required, disabled, checked, и их тоже можно выставлять сразу, без лишних условий:
input.required = mark < 3;
button.disabled = Boolean(input.value);
checkbox.checked = isNewUser && isActionAvailable;
Ещё по условию можно переключать классы:
if (mark < 3) {
elem.classList.add('hidden');
} else {
elem.classList.remove('hidden');
}
У classList есть ещё метод toggle. У него два параметра: имя класса, и логический параметр, о котором студенты забывают. Работает он так:
- если второй параметр
true, то класс добавится; - если
false, то класс удалится.
То есть, вместо пяти строк можно снова написать одну:
elem.classList.toggle('hidden', mark < 3);
Выносите части условий в переменные
В этом коде при беглом взгляде не понятно, что происходит:
if ( (! inputText.required || inputText.value) && (! inputName.required || inputName.value)) {
doSomething();
}
каждый раз приходится спотыкаться и разбираться. Сделать этот код читаемым легко: достаточно вынести связанные куски в переменные.
var isTextValid = ! inputText.required || inputText.value;
var isNameValid = ! inputName.required || inputName.value;
if (isTextValid && isNameValid) {
doSomething();
}
или вынести проверку в функцию:
function isValid(input) {
return ! input.required || input.value;
}
if (isValid(inputText) && isValid(inputName)) {
doSomething();
}
Научитесь работать с логическими операторами
Разберитесь, как работают &&, || и !. У моего студента в проекте был такой код:
if (a && b) {
doSomething();
}
if ( ! a || ! b) {
doOtherthing();
}
Если вы работали с алгеброй логики, то уже поняли, в чём подвох. Если нет, то в любой непонятной ситуации рисуйте таблицы истинности. Это когда вы рассматриваете, какой результат будет у всего выражения, в зависимости от значений переменных. Например:
- если
a === falseиb === false, тоa && b === false; - если
a === falseиb === true, тоa && b === false; - если
a === trueиb === false, тоa && b === false; - если
a === trueиb === true, тоa && b === true.
Это можно записать в таблицу (вместо false обычно пишут 0, а вместо true — 1):
Значениеa | Значениеb | Значениеa && b |
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
a && bПопробуем составить таблицу истинности для второго условия: ! a || ! b. Если a === false и b === false, то:
! a || ! b
↓
! false || ! false
↓
true || true
↓
true
То есть если a === false и b === false, то ! a || ! b === true. Остальные случаи рассмотрим аналогично. Получится такая таблица:
Значениеa | Значениеb | Значение! a || ! b |
| 0 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
! a || ! bЗаметьте, у второе выражение истинно как раз в тех случаях, когда первое ложно, и наоборот. Поставим их рядом для сравнения:
Значениеa | Значениеb | Значениеa && b | Значение! a || ! b |
| 0 | 0 | 0 | 1 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 0 |
a && b и ! a || ! bТо есть если:
a && b === false
то:
! a || ! b === true
и наоборот, если:
a && b === true
то:
! a || ! b === false
Получается, что вместо:
if (a && b) {
doSomething();
}
if ( ! a || ! b) {
doOtherthing();
}
можно писать:
if (a && b) {
doSomething();
} else {
doOtherthing();
}
Потренируйтесь вычислять логические выражения в уме.