pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://learn.javascript.ru/logical-operators

= {"RUB":1,"EUR":0.010419872068936699,"USD":0.012074025658125558,"AMD":4.544619441079346};Логические операторы
9 ноября 2023 г.

Логические операторы

В JavaScript есть семь логических операторов:

  • || (ИЛИ)
    • ||= (Оператор логического присваивания ИЛИ)
  • && (И)
    • &&= (Оператор логического присваивания И)
  • ! (НЕ)
  • ?? (Оператор нулевого слияния)
    • ??= (Оператор нулевого присваивания)

Здесь мы рассмотрим первые пять, операторы ?? и ??= будут в следующей статье.

Несмотря на своё название, данные операторы могут применяться к значениям любых типов. Полученные результаты также могут иметь различный тип.

Давайте рассмотрим их подробнее.

|| (ИЛИ)

Оператор «ИЛИ» выглядит как двойной символ вертикальной черты:

result = a || b;

Традиционно в программировании ИЛИ предназначено только для манипулирования булевыми значениями: в случае, если какой-либо из аргументов true, он вернёт true, в противоположной ситуации возвращается false.

В JavaScript, как мы увидим далее, этот оператор работает несколько иным образом. Но давайте сперва посмотрим, что происходит с булевыми значениями.

Существует всего четыре возможные логические комбинации:

alert( true || true );   // true
alert( false || true );  // true
alert( true || false );  // true
alert( false || false ); // false

Как мы можем наблюдать, результат операций всегда равен true, за исключением случая, когда оба аргумента false.

Если значение не логического типа, то оно к нему приводится в целях вычислений.

Например, число 1 будет воспринято как true, а 0 – как false:

if (1 || 0) { // работает как if( true || false )
  alert( 'истинно!' );
}

Обычно оператор || используется в if для проверки истинности любого из заданных условий.

К примеру:

let hour = 9;

if (hour < 10 || hour > 18) {
  alert( 'Офис закрыт.' );
}

Можно передать и больше условий:

let hour = 12;
let isWeekend = true;

if (hour < 10 || hour > 18 || isWeekend) {
  alert( 'Офис закрыт.' ); // это выходной
}

ИЛИ "||" находит первое истинное значение

Описанная выше логика соответствует традиционной. Теперь давайте поработаем с «дополнительными» возможностями JavaScript.

Расширенный алгоритм работает следующим образом.

При выполнении ИЛИ || с несколькими значениями:

result = value1 || value2 || value3;

Оператор || выполняет следующие действия:

  • Вычисляет операнды слева направо.
  • Каждый операнд конвертирует в логическое значение. Если результат true, останавливается и возвращает исходное значение этого операнда.
  • Если все операнды являются ложными (false), возвращает последний из них.

Значение возвращается в исходном виде, без преобразования.

Другими словами, цепочка ИЛИ || возвращает первое истинное значение или последнее, если такое значение не найдено.

Например:

alert( 1 || 0 ); // 1 (1 - истинное значение)
alert( true || 'какая-то строка' ); // true

alert( null || 1 ); // 1 (первое истинное значение)
alert( null || 0 || 1 ); // 1 (первое истинное значение)
alert( undefined || null || 0 ); // 0 (поскольку все ложно, возвращается последнее значение)

Это делает возможным более интересное применение оператора по сравнению с «чистым, традиционным, только булевым ИЛИ».

  1. Получение первого истинного значения из списка переменных или выражений.

    Например, у нас есть переменные firstName, lastName и nickName, все они необязательные (т.е. они могут быть неопределенными или иметь ложные значения).

    Давайте воспользуемся оператором ИЛИ ||, чтобы выбрать ту переменную, в которой есть данные, и показать её (или «Аноним», если ни в одной переменной данных нет):

    let firstName = "";
    let lastName = "";
    let nickName = "Суперкодер";
    
    alert( firstName || lastName || nickName || "Аноним"); // Суперкодер

    Если бы все переменные были ложными, в качестве результата мы бы наблюдали "Аноним".

  2. Сокращённое вычисление.

    Ещё одной отличительной особенностью оператора ИЛИ || является так называемое «сокращённое вычисление».

    Это означает, что ИЛИ || обрабатывает свои операнды до тех пор, пока не будет достигнуто первое истинностное значение, и затем это значение сразу же возвращается, даже не затрагивая другие операнды.

    Важность этой особенности становится очевидной, если операнд – это не просто значение, а выражение с сопутствующим эффектом, как, например, присваивание переменной или вызов функции.

    В приведенном ниже примере срабатывает только второй alert:

    true || alert("никогда не сработает");
    false || alert("сработает");

    В первой строке оператор ИЛИ || останавливает выполнение сразу после того, как сталкивается с истинным значением (true), поэтому сообщение не показывается.

    Иногда люди используют эту возможность для выполнения инструкций только в том случае, если условие в левой части является ложным.

||= (Логическое присваивание ИЛИ)

Новая возможность
Эта возможность была добавлена в язык недавно. В старых браузерах может понадобиться полифил.

Оператор логического присваивания ИЛИ ||= записывается как обычный ИЛИ || с добавлением символа присваивания =. Такая запись не случайна, так как результат выполнения данного оператора напрямую зависит от действий уже известного нам ||.

Вот его синтаксис:

a ||= b;

Оператор ||= принимает два операнда и выполняет следующие действия:

  • Вычисляет операнды слева направо.
  • Конвертирует a в логическое значение.
  • Если a ложно, присваивает a значение b.

Концепция оператора ||= заключается в «сокращённом вычислении», принцип работы которого мы разобрали ранее.

Теперь давайте перепишем a ||= b под вид «сокращённого вычисления»:

a || (a = b);

Мы уже знаем, что ИЛИ || возвращает первое истинное значение, поэтому, если a является таковым, вычисление до правой части выражения не дойдёт.

Вот пример с очевидным использованием оператора ||=:

let johnHasCar = false;

johnHasCar ||= "У Джона нет машины!"; // то же самое, что false || (johnHasCar = "...")

alert( johnHasCar ); // "У Джона нет машины!"

…А здесь происходит преобразование к логическому значению:

let manufacturer = ""; // оператор ||= преобразует пустую строку "" к логическому значению false

manufacturer ||= "Неизвестный производитель"; // то же самое, что false || (manufacturer = "...")

alert( manufacturer ); // "Неизвестный производитель"

Оператор логического присваивания ИЛИ ||= – это «синтаксический сахар», добавленный в язык в качестве более короткого варианта записи if-выражений с присваиванием.

Мы можем переписать приведённые выше примеры с использованием обычного if:

let johnHasCar = false;

if (johnHasCar == false) {
  johnHasCar = "У Джона нет машины!";
}

alert(johnHasCar); // "У Джона нет машины!"

let manufacturer = "";

if (manufacturer == false) {
  manufacturer = "Неизвестный производитель";
}

alert(manufacturer); // "Неизвестный производитель"

&& (И)

Оператор И пишется как два амперсанда &&:

result = a && b;

В традиционном программировании И возвращает true, если оба аргумента истинны, а иначе – false:

alert( true && true );   // true
alert( false && true );  // false
alert( true && false );  // false
alert( false && false ); // false

Пример с if:

let hour = 12;
let minute = 30;

if (hour == 12 && minute == 30) {
  alert( 'Время 12:30' );
}

Как и в случае с ИЛИ, любое значение допускается в качестве операнда И:

if (1 && 0) { // вычисляется как true && false
  alert( "не сработает, так как результат ложный" );
}

И «&&» находит первое ложное значение

При нескольких подряд операторах И:

result = value1 && value2 && value3;

Оператор && выполняет следующие действия:

  • Вычисляет операнды слева направо.
  • Каждый операнд преобразует в логическое значение. Если результат false, останавливается и возвращает исходное значение этого операнда.
  • Если все операнды были истинными, возвращается последний.

Другими словами, И возвращает первое ложное значение. Или последнее, если ничего не найдено.

Вышеуказанные правила схожи с поведением ИЛИ. Разница в том, что И возвращает первое ложное значение, а ИЛИ –  первое истинное.

Примеры:

// Если первый операнд истинный,
// И возвращает второй:
alert( 1 && 0 ); // 0
alert( 1 && 5 ); // 5

// Если первый операнд ложный,
// И возвращает его. Второй операнд игнорируется
alert( null && 5 ); // null
alert( 0 && "какая-то строка" ); // 0

Можно передать несколько значений подряд. В таком случае возвратится первое «ложное» значение, на котором остановились вычисления.

alert( 1 && 2 && null && 3 ); // null

Когда все значения верны, возвращается последнее

alert( 1 && 2 && 3 ); // 3
Приоритет оператора && больше, чем у ||

Приоритет оператора И && больше, чем ИЛИ ||, так что он выполняется раньше.

Таким образом, код a && b || c && d по существу такой же, как если бы выражения && были в круглых скобках: (a && b) || (c && d).

Не заменяйте if на || или &&

Иногда люди используют оператор И && как «более короткий способ записи if-выражения».

Например:

let x = 1;

(x > 0) && alert( 'x больше нуля!' );

Инструкция в правой части && будет выполнена только в том случае, если вычисление дойдет до нее. То есть, только если (x > 0) истинно.

Таким образом, мы имеем аналог для следующего кода:

let x = 1;

if (x > 0) alert( 'x больше нуля!' );

Несмотря на то, что вариант с && кажется более коротким, if более нагляден и, как правило, более читабелен. Поэтому мы рекомендуем использовать каждую конструкцию по назначению: использовать if, если нам нужно if, и использовать &&, если нам нужно И.

&&= (Логическое присваивание И)

Новая возможность
Эта возможность была добавлена в язык недавно. В старых браузерах может понадобиться полифил.

Оператор логического присваивания И &&= записывается как два амперсанда && и символ присваивания =.

Вот его синтаксис:

a &&= b;

Принцип действия &&= практически такой же, как и у оператора логического присваивания ИЛИ ||=. Единственное отличие заключается в том, что &&= присвоит a значение b только в том случае, если a истинно.

Концепция оператора логического присваивания И &&= также основывается на «сокращённом вычислении»:

a && (a = b);

Пример использования:

let greeting = "Привет"; // строка непустая, поэтому будет преобразована к логическому значению true оператором &&=

greeting &&= greeting + ", пользователь!"; // то же самое, что true && (greeting = greeting + "...")

alert( greeting ) // "Привет, пользователь!"

Так как оператор логического присваивания И &&= также как и ||= является «синтаксическим сахаром», мы можем без проблем переписать пример выше с использованием привычного для нас if:

let greeting = "Привет";

if (greeting) {
  greeting = greeting + ", пользователь!"
}

alert( greeting ) // "Привет, пользователь!"

На практике, в отличие от ||=, оператор &&= используется достаточно редко – обычно, в комбинации с более сложными языковыми конструкциями, о которых мы будем говорить позже. Подобрать контекст для применения данного оператора – довольно непростая задача.

! (НЕ)

Оператор НЕ представлен восклицательным знаком !.

Синтаксис довольно прост:

result = !value;

Оператор принимает один аргумент и выполняет следующие действия:

  1. Сначала приводит аргумент к логическому типу true/false.
  2. Затем возвращает противоположное значение.

Например:

alert( !true ); // false
alert( !0 ); // true

В частности, двойное НЕ !! используют для преобразования значений к логическому типу:

alert( !!"непустая строка" ); // true
alert( !!null ); // false

То есть первое НЕ преобразует значение в логическое значение и возвращает обратное, а второе НЕ снова инвертирует его. В конце мы имеем простое преобразование значения в логическое.

Есть немного более подробный способ сделать то же самое – встроенная функция Boolean:

alert( Boolean("непустая строка") ); // true
alert( Boolean(null) ); // false

Приоритет НЕ ! является наивысшим из всех логических операторов, поэтому он всегда выполняется первым, перед && или ||.

Задачи

важность: 5

Что выведет код ниже?

alert( null || 2 || undefined );

Ответ: 2, это первое значение, которое в логическом контексте даст true.

alert( null || 2 || undefined );
важность: 3

Что выведет код ниже?

alert( alert(1) || 2 || alert(3) );

Ответ: сначала 1, затем 2.

alert( alert(1) || 2 || alert(3) );

Вызов alert не возвращает значения, или, иначе говоря, возвращает undefined.

  1. Первый оператор ИЛИ || выполнит первый alert(1).
  2. Получит undefined и пойдёт дальше, ко второму операнду в поисках истинного значения.
  3. Так как второй операнд 2 является истинным, то вычисления завершатся, результатом undefined || 2 будет 2, которое будет выведено внешним alert( .... ).

Второй оператор || не будет выполнен, выполнение до alert(3) не дойдёт, поэтому 3 выведено не будет.

важность: 5

Что выведет код ниже?

alert( 1 && null && 2 );

Ответ: null, потому что это первое «ложное» значение из списка.

alert( 1 && null && 2 );
важность: 3

Что выведет код ниже?

alert( alert(1) && alert(2) );

Ответ: 1, а затем undefined.

alert( alert(1) && alert(2) );

Вызов alert не возвращает значения, или, иначе говоря, возвращает undefined.

Поэтому до правого alert дело не дойдёт, вычисления закончатся на левом.

важность: 5

Что выведет код ниже?

alert( null || 2 && 3 || 4 );

Ответ: 3.

alert( null || 2 && 3 || 4 );

Приоритет оператора && выше, чем ||, поэтому он выполнится первым.

Результат 2 && 3 = 3, поэтому выражение приобретает вид:

null || 3 || 4

Теперь результатом является первое истинное значение: 3.

важность: 2

Что выведет код ниже?

let value = NaN;

value &&= 10;
value ||= 20;
value &&= 30;
value ||= 40;

alert(value);

Ответ: 30.

let value = NaN;

value &&= 10;
value ||= 20;
value &&= 30;
value ||= 40;

alert(value);

Порядок выполнения данного кода:

  1. value &&= 10
    • value=NaN
    • NaN конвертируется в логическое значение false
    • value ложно, поэтому присваивание не срабатывает
  2. value ||= 20
    • value=NaN
    • NaN конвертируется в логическое значение false
    • value ложно, поэтому присваивание срабатывает
  3. value &&= 30
    • value=20
    • 20 конвертируется в логическое значение true
    • value истинно, поэтому присваивание срабатывает
  4. value ||= 40
    • value=30
    • 30 конвертируется в логическое значение true
    • value истинно, поэтому присваивание не срабатывает
важность: 3

Напишите условие if для проверки, что переменная age находится в диапазоне между 14 и 90 включительно.

«Включительно» означает, что значение переменной age может быть равно 14 или 90.

if (age >= 14 && age <= 90)
важность: 3

Напишите условие if для проверки, что значение переменной age НЕ находится в диапазоне 14 и 90 включительно.

Напишите два варианта: первый с использованием оператора НЕ !, второй – без этого оператора.

Первый вариант:

if (!(age >= 14 && age <= 90))

Второй вариант:

if (age < 14 || age > 90)
важность: 5

Какие из перечисленных ниже alert выполнятся?

Какие конкретно значения будут результатами выражений в условиях if(...)?

if (-1 || 0) alert( 'first' );
if (-1 && 0) alert( 'second' );
if (null || -1 && 1) alert( 'third' );

Ответ: первое и третье выполнятся.

Подробности:

// Выполнится.
// Результат -1 || 0 = -1, в логическом контексте true
if (-1 || 0) alert( 'first' );

// Не выполнится
// -1 && 0 = 0,  в логическом контексте false
if (-1 && 0) alert( 'second' );

// Выполнится
// оператор && имеет больший приоритет, чем ||
// так что -1 && 1 выполнится раньше
// вычисления: null || -1 && 1  ->  null || 1  ->  1
if (null || -1 && 1) alert( 'third' );
важность: 3

Напишите код, который будет спрашивать логин с помощью prompt.

Если посетитель вводит «Админ», то prompt запрашивает пароль, если ничего не введено или нажата клавиша Esc – показать «Отменено», в противном случае отобразить «Я вас не знаю».

Пароль проверять так:

  • Если введён пароль «Я главный», то выводить «Здравствуйте!»,
  • Иначе – «Неверный пароль»,
  • При отмене или в случае если ничего не введено – «Отменено».

Блок-схема:

Для решения используйте вложенные блоки if. Обращайте внимание на стиль и читаемость кода.

Подсказка: передача пустого ввода в приглашение prompt возвращает пустую строку ''. Нажатие клавиши Esc во время запроса возвращает null.

Запустить демо

let userName = prompt("Кто там?", '');

if (userName === 'Админ') {

  let pass = prompt('Пароль?', '');

  if (pass === 'Я главный') {
    alert( 'Здравствуйте!' );
  } else if (pass === '' || pass === null) {
    alert( 'Отменено' );
  } else {
    alert( 'Неверный пароль' );
  }

} else if (userName === '' || userName === null) {
  alert( 'Отменено' );
} else {
  alert( "Я вас не знаю" );
}

Обратите внимание на вертикальные отступы внутри блоков if. Они технически не требуются, но делают код более читаемым.

Карта учебника
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy