В JavaScript існує чотири логічні оператори: || (АБО), && (І), ! (НЕ), ?? (оператор null-об’єднання). В цьому розділі ми розглянемо перші три оператори, а оператор ?? — в наступному розділі.
Хоча вони називаються “логічними”, вони можуть бути застосовані до значень будь-якого типу, не тільки булевих. Їх результати також можуть бути будь-якого типу.
Подивимось більш детально.
|| (АБО)
Оператор “АБО” представлений двома символами вертикальної лінії:
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) { // працює так само, як ( true || false )
alert( 'правдиво!' );
}
У більшості випадків АБО || використовується в інструкціях if, щоб перевірити, чи є будь-яка із заданих умов true.
Наприклад:
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( null || 1 ); // 1 (1 є першим правдивим значенням)
alert( null || 0 || 1 ); // 1 (перше правдиве значення)
alert( undefined || null || 0 ); // 0 (усі хибні, повертається останнє значення)
Це призводить до цікавого використання, у порівнянні з “чистим, класичним, виключно-булевим АБО”.
-
Отримання першого істинного значення зі списку змінних або виразів.
Наприклад, маємо змінні
firstName,lastNameтаnickName, усі необов’язкові (тобто вони можуть бути невизначеними або мати хибні значення).Використаємо АБО
||, щоб вибрати ту змінну, яка має дані, і виведемо її (або рядок"Анонім", якщо жодна змінна не має даних):let firstName = ""; let lastName = ""; let nickName = "СуперКодер"; alert( firstName || lastName || nickName || "Анонім"); // СуперКодерЯкщо всі змінні мали б порожні рядки, тоді показалося слово
"Анонім". -
Обчислення короткого замикання.
Іншою особливістю оператора АБО
||є так зване “обчислення короткого замикання”.Це означає, що оператор
||опрацьовує аргументи доти, доки не досягається перше правдиве значення, після чого це значення негайно повертається, без подальшого опрацювання решти аргументів.Важливість такої особливості стає очевидною, якщо операнд є не просто змінною, а виразом із побічним ефектом, як-от присвоєння змінної або виклик функції.
У наведеному нижче прикладі виведеться лише друге повідомлення:
true || alert("не виведеться"); false || alert("виведеться");В першому рядку оператор АБО
||зупиняє виконання відразу після того, як “побачить” що лівий вираз єtrue, тожalertне виконається.Деколи таку конструкцію використовують, щоб виконувати команди лише при хибності умови ліворуч від оператора.
&& (І)
Оператор І представлений двома амперсандами &&:
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 > 0) є істинним.
Тому, власне, ми маємо аналог для:
let x = 1;
if (x > 0) alert( 'Більше за нуль!' );
Хоча варіант з && видається коротшим, конструкція з if є більш очевидною і зазвичай більш читабельною. Тому ми рекомендуємо використовувати кожну конструкцію за своїм призначенням: використовуємо if, якщо нам потрібна інструкція if, і використовуємо &&, якщо нам потрібен оператор І.
! (НЕ)
Булевий оператор НЕ представлений знаком оклику !.
Синтаксис дуже простий:
result = !value;
Оператор приймає один аргумент і виконує наступне:
- Перетворює операнд на булевий тип:
true/false. - Повертає зворотне значення.
Наприклад:
alert( !true ); // false
alert( !0 ); // true
Подвійний НЕ !! іноді використовується для перетворення значення на булевий тип:
alert( !!"не пустий рядок" ); // true
alert( !!null ); // false
Тобто, перший НЕ перетворює значення на булеве і повертає зворотне, а другий НЕ інвертує його знову. Зрештою ми маємо просте перетворення значень на булевий тип.
Є трохи довший спосіб зробити те ж саме – вбудована функція Boolean:
alert( Boolean("не пустий рядок") ); // true
alert( Boolean(null) ); // false
Пріоритет НЕ ! є найвищим серед усіх логічних операторів, тому він завжди виконується першим, перед && або ||.
Коментарі
<code>, для кількох рядків – обгорніть їх тегом<pre>, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)