Такой простой Boolean
У 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();
}
Потренируйтесь вычислять логические выражения в уме.