В JavaScript есть четыре логических оператора: ||
(ИЛИ), &&
(И), !
(НЕТ), ??
(Нулевое слияние). Здесь мы рассмотрим первые три: ??
оператор в следующей статье.
Хотя их называют «логическими», их можно применять к значениям любого типа, а не только к логическим. Их результат также может быть любого типа.
Давайте посмотрим детали.
Оператор «ИЛИ» представлен двумя символами вертикальных линий:
результат = а || б;
В классическом программировании логическое ИЛИ предназначено только для манипулирования логическими значениями. Если какой-либо из его аргументов имеет значение true
, он возвращает true
, в противном случае возвращается false
.
В JavaScript этот оператор немного сложнее и мощнее. Но сначала давайте посмотрим, что происходит с логическими значениями.
Возможны четыре логические комбинации:
предупреждение(истина || правда); // истинный предупреждение(ложь || правда); // истинный предупреждение(истина || ложь); // истинный предупреждение(ложь || ложь); // ЛОЖЬ
Как мы видим, результат всегда true
за исключением случая, когда оба операнда имеют false
.
Если операнд не является логическим значением, для оценки он преобразуется в логическое значение.
Например, число 1
рассматривается как true
, число 0
как false
:
if (1 || 0) { // работает так же, как if( true || false ) alert('правда!'); }
В большинстве случаев ИЛИ ||
используется в операторе if
для проверки true
любого из заданных условий.
Например:
пусть час = 9; if (час < 10 || час > 18) { alert('Офис закрыт.'); }
Мы можем передать больше условий:
пусть час = 12; пусть isWeekend = true; if (час < 10 || час > 18 || isWeekend) { alert('Офис закрыт.'); // сегодня выходные }
Описанная выше логика в некоторой степени классическая. Теперь давайте добавим «дополнительные» возможности JavaScript.
Расширенный алгоритм работает следующим образом.
Учитывая несколько значений OR:
результат = значение1 || значение2 || значение3;
операционная ||
оператор делает следующее:
Оценивает операнды слева направо.
Для каждого операнда преобразует его в логическое значение. Если результат равен true
, останавливается и возвращает исходное значение этого операнда.
Если все операнды были оценены (т.е. все они были false
), возвращает последний операнд.
Значение возвращается в исходной форме, без преобразования.
Другими словами, цепочка ИЛИ ||
возвращает первое истинное значение или последнее, если истинное значение не найдено.
Например:
оповещение(1 || 0); // 1 (1 — правда) предупреждение (ноль || 1); // 1 (1 — первое истинное значение) предупреждение (ноль || 0 || 1); // 1 (первое истинное значение) предупреждение (не определено || ноль || 0); // 0 (все ложно, возвращает последнее значение)
Это приводит к некоторому интересному использованию по сравнению с «чистым классическим логическим ИЛИ».
Получение первого истинного значения из списка переменных или выражений.
Например, у нас есть переменные firstName
, lastName
и nickName
, все они необязательные (т.е. могут быть неопределенными или иметь ложные значения).
Давайте используем ИЛИ ||
чтобы выбрать тот, у которого есть данные, и показать его (или "Anonymous"
если ничего не установлено):
пусть firstName = ""; пусть LastName = ""; let nickName = "Суперкодер"; alert( FirstName || LastName || NickName || "Анонимный"); // Суперкодер
Если бы все переменные были ложными, появилось бы "Anonymous"
.
Оценка короткого замыкания.
Еще одна особенность OR ||
оператором является так называемая оценка «короткого замыкания».
Это означает, что ||
обрабатывает свои аргументы до тех пор, пока не будет достигнуто первое истинное значение, а затем значение возвращается немедленно, даже не касаясь другого аргумента.
Важность этой возможности становится очевидной, если операнд является не просто значением, а выражением с побочным эффектом, например присвоением переменной или вызовом функции.
В приведенном ниже примере печатается только второе сообщение:
правда || alert("не распечатано"); ложь || Оповещение("Напечатано");
В первой строке OR ||
Оператор немедленно останавливает оценку, увидев true
, поэтому alert
не запускается.
Иногда люди используют эту функцию для выполнения команд, только если условие в левой части ложно.
Оператор AND представлен двумя амперсандами &&
:
результат = а && б;
В классическом программировании AND возвращает true
если оба операнда истинны, и false
в противном случае:
предупреждение (истина && правда); // истинный предупреждение (ложь && истина); // ЛОЖЬ предупреждение (истина && ложь); // ЛОЖЬ предупреждение (ложь && ложь); // ЛОЖЬ
Пример с if
:
пусть час = 12; пусть минута = 30; if (час == 12 && минута == 30) { alert('Время 12:30'); }
Как и в случае с OR, в качестве операнда AND допускается любое значение:
if (1 && 0) { // оценивается как true && false alert("не сработает, потому что результат ложный"); }
Учитывая несколько значений AND:
результат = значение1 && значение2 && значение3;
Оператор AND &&
выполняет следующие действия:
Оценивает операнды слева направо.
Для каждого операнда преобразует его в логическое значение. Если результат false
, останавливается и возвращает исходное значение этого операнда.
Если все операнды были оценены (т.е. все были правдивы), возвращается последний операнд.
Другими словами, AND возвращает первое ложное значение или последнее значение, если оно не найдено.
Приведенные выше правила аналогичны OR. Разница в том, что AND возвращает первое ложное значение, а OR возвращает первое истинное значение.
Примеры:
// если первый операнд правдив, // И возвращает второй операнд: предупреждение (1 && 0); // 0 предупреждение( 1 && 5 ); // 5 // если первый операнд ложный, // И возвращает его. Второй операнд игнорируется предупреждение (ноль && 5); // нулевой alert(0 && "несмотря ни на что"); // 0
Мы также можем передать несколько значений подряд. Посмотрите, как возвращается первый ложный:
предупреждение( 1 && 2 && null && 3 ); // нулевой
Когда все значения верны, возвращается последнее значение:
предупреждение( 1 && 2 && 3 ); // 3, последний
Приоритет AND &&
выше, чем OR ||
Приоритет оператора AND &&
выше, чем у оператора OR ||
.
Итак, код a && b || c && d
по сути то же самое, как если бы выражения &&
были заключены в круглые скобки: (a && b) || (c && d)
.
Не заменяйте, if
на ||
или &&
Иногда люди используют оператор AND &&
как «более короткий способ записи if
».
Например:
пусть х = 1; (x > 0) && alert( 'Больше нуля!');
Действие в правой части &&
будет выполнено только в том случае, если оценка достигнет его. То есть, только если (x > 0)
истинно.
Итак, по сути, у нас есть аналог для:
пусть х = 1; if (x > 0) alert('Больше нуля!');
Хотя вариант с &&
выглядит короче, if
более очевиден и имеет тенденцию быть немного более читабельным. Поэтому мы рекомендуем использовать каждую конструкцию по назначению: использовать if
, если хотим if
и использовать &&
если хотим AND.
Логический оператор NOT обозначается восклицательным знаком !
.
Синтаксис довольно прост:
результат = !значение;
Оператор принимает один аргумент и выполняет следующие действия:
Преобразует операнд в логический тип: true/false
.
Возвращает обратное значение.
Например:
предупреждение(!истина); // ЛОЖЬ предупреждение( !0 ); // истинный
Двойное НЕТ !!
иногда используется для преобразования значения в логический тип:
alert( !!"непустая строка" ); // истинный оповещение( !!ноль ); // ЛОЖЬ
То есть первое NOT преобразует значение в логическое значение и возвращает обратное значение, а второе NOT снова инвертирует его. В конце концов мы имеем простое преобразование значения в логическое значение.
Есть немного более подробный способ сделать то же самое — встроенная Boolean
функция:
alert( Boolean("непустая строка")); // истинный Предупреждение (логическое значение (ноль)); // ЛОЖЬ
Приоритет NOT !
является высшим из всех логических операторов, поэтому он всегда выполняется первым, перед &&
или ||
.
важность: 5
Что будет выводить приведенный ниже код?
предупреждение (ноль || 2 || неопределенное);
Ответ — 2
, это первое истинное значение.
предупреждение (ноль || 2 || неопределенное);
важность: 3
Что выведет код ниже?
предупреждение(предупреждение(1) || 2 || предупреждение(3) );
Ответ: сначала 1
, потом 2
.
предупреждение(предупреждение(1) || 2 || предупреждение(3) );
Вызов alert
не возвращает значения. Или, другими словами, он возвращает undefined
.
Первое ИЛИ ||
оценивает свой левый операнд alert(1)
. Это показывает первое сообщение с 1
.
alert
возвращает undefined
, поэтому OR переходит ко второму операнду в поисках истинного значения.
Второй операнд 2
является правдивым, поэтому выполнение останавливается, возвращается 2
, а затем отображается внешним предупреждением.
3
не будет, потому что оценка не доходит до alert(3)
.
важность: 5
Что этот код покажет?
предупреждение( 1 && ноль && 2 );
Ответ: null
, потому что это первое ложное значение из списка.
предупреждение (1 && ноль && 2);
важность: 3
Что покажет этот код?
оповещение( оповещение(1) && оповещение(2) );
Ответ: 1
, а затем undefined
.
оповещение( оповещение(1) && оповещение(2) );
Вызов alert
возвращает undefined
(он просто показывает сообщение, поэтому никакого значимого возврата нет).
По этой причине &&
оценивает левый операнд (выводит 1
) и немедленно останавливается, поскольку undefined
— это ложное значение. А &&
ищет ложное значение и возвращает его, вот и все.
важность: 5
Каков будет результат?
предупреждение(ноль || 2 && 3 || 4 );
Ответ: 3
.
предупреждение(ноль || 2 && 3 || 4 );
Приоритет AND &&
выше, чем ||
, поэтому он выполняется первым.
Результат 2 && 3 = 3
, поэтому выражение принимает вид:
ноль || 3 || 4
Теперь результатом является первое истинное значение: 3
.
важность: 3
Напишите условие if
, проверяющее, что age
находится в диапазоне от 14
до 90
включительно.
«Инклюзивно» означает, что age
может достигать границ 14
или 90
.
if (возраст >= 14 && возраст <= 90)
важность: 3
Напишите условие if
чтобы проверить, что age
НЕ находится в диапазоне от 14
до 90
включительно.
Создайте два варианта: первый с использованием NOT !
, второй – без него.
Первый вариант:
if (!(возраст >= 14 && возраст <= 90))
Второй вариант:
если (возраст < 14 || возраст > 90)
важность: 5
Какое из этих alert
будет выполнено?
Каковы будут результаты выражений внутри if(...)
?
if (-1 || 0) alert( 'первый'); if (-1 && 0) alert( 'секунда'); if (null || -1 && 1) alert( 'третий');
Ответ: выполнятся первое и третье.
Подробности:
// Бежит. // Результат -1 || 0 = -1, правда if (-1 || 0) alert( 'первый'); // Не запускается // -1 && 0 = 0, ложь if (-1 && 0) alert( 'секунда'); // Выполняется // Оператор && имеет более высокий приоритет, чем || // поэтому -1 && 1 выполняется первым, давая нам цепочку: // ноль || -1 && 1 -> ноль || 1 -> 1 if (null || -1 && 1) alert( 'третий');
важность: 3
Напишите код, который запрашивает вход в систему с помощью prompt
.
Если посетитель вводит "Admin"
, то prompt
пароль, если введена пустая строка или Esc – показать «Отменено», если это другая строка – то показать «Я вас не знаю».
Пароль проверяется следующим образом:
Если оно равно «TheMaster», покажите «Добро пожаловать!»,
Другая строка – показать «Неправильный пароль»,
Для пустой строки или отмененного ввода покажите «Отменено».
Схема:
Пожалуйста, используйте вложенные блоки if
. Помните об общей читаемости кода.
Подсказка: передача пустого ввода в приглашение возвращает пустую строку ''
. Нажатие ESC во время приглашения возвращает null
.
Запустить демо-версию
let userName = Prompt("Кто там?", ''); if (имя пользователя === 'Администратор') { let pass = Prompt('Пароль?', ''); if (pass === 'TheMaster') { alert('Добро пожаловать!'); } else if (pass === '' || pass === null) { Предупреждение('Отменено'); } еще { alert('Неправильный пароль'); } } else if (userName === '' || userName === null) { Предупреждение('Отменено'); } еще { alert("Я тебя не знаю"); }
Обратите внимание на вертикальные отступы внутри блоков if
. Технически они не требуются, но делают код более читабельным.