JavaScript: Отрицание
Наряду с логическими операторами И (&&) и ИЛИ (||), часто используется операция «отрицание». Она меняет логическое значение на противоположное. В JavaScript отрицанию соответствует унарный оператор !:
!true; // false
!false; // trueНапример, если есть функция, проверяющая чётность числа, то с помощью отрицания можно выполнить проверку нечётности:
const isEven = (number) => number % 2 === 0;
isEven(10); // true
!isEven(10); // falseМы просто добавили ! слева от вызова функции и получили обратное действие. Отрицание позволяет выражать задуманные правила в коде без написания новых функций.
Двойное отрицание
А что, если написать !!isEven(10)? Внезапно, но код сработает. В логике двойное отрицание равносильно отсутствию отрицания:
isEven(10); // true
!isEven(10); // false
!!isEven(10); // trueКомбинирование с && и ||
! можно комбинировать с && и ||. Среди логических операторов у отрицания наивысший приоритет, поэтому оно применяется первым:
!true || true; // (!true) || true => false || true => true
!true && false; // (!true) && false => false && false => falseСкобки меняют порядок вычисления:
!(true || true); // !true => false
!(true && false); // !false => trueПрактический пример — функция проверяет, может ли водитель сесть за руль: нужны права и трезвость:
const canDrive = (hasLicense, isDrunk) => hasLicense && !isDrunk;
console.log(canDrive(true, false)); // => true (есть права, трезвый)
console.log(canDrive(true, true)); // => false (есть права, но пьяный)
console.log(canDrive(false, false)); // => false (нет прав)Законы де Моргана
При работе со сложными логическими выражениями бывает нужно инвертировать их или переписать в эквивалентную, более читаемую форму. Для этого существуют законы де Моргана — два правила, описывающих, как отрицание распределяется по составному выражению:
!(a && b) === !a || !b;
!(a || b) === !a && !b;Первый закон: отрицание конъюнкции равно дизъюнкции отрицаний. Проверим:
!(true && false); // !false => true
!true || !false; // false || true => trueВторой закон: отрицание дизъюнкции равно конъюнкции отрицаний:
!(true || false); // !true => false
!true && !false; // false && true => falseНа практике законы де Моргана помогают упрощать условия. Например, вместо !(isAdmin || isModerator) можно написать !isAdmin && !isModerator — читается как «не администратор и не модератор».
Задание
Напишите две функции:
isPalindrome(str)— возвращаетtrue, если строка является палиндромом (читается одинаково в обоих направлениях).isNotPalindrome(str)— возвращаетtrue, если строка не является палиндромом.
isPalindrome("level"); // => true
isPalindrome("hello"); // => false
isNotPalindrome("level"); // => false
isNotPalindrome("hello"); // => true
// Строки в функции могут быть переданы в любом регистре
// Поэтому сначала приведите строку к нижнему регистру методом .toLowerCase()
isPalindrome("Wow"); // => true
isNotPalindrome("Wow"); // => falseИспользуйте метод .split(''), .reverse(), .join('') для разворота строки.
Полезное
JavaScript: Отрицание
Наряду с логическими операторами И (&&) и ИЛИ (||), часто используется операция «отрицание». Она меняет логическое значение на противоположное. В JavaScript отрицанию соответствует унарный оператор !:
!true; // false
!false; // trueНапример, если есть функция, проверяющая чётность числа, то с помощью отрицания можно выполнить проверку нечётности:
const isEven = (number) => number % 2 === 0;
isEven(10); // true
!isEven(10); // falseМы просто добавили ! слева от вызова функции и получили обратное действие. Отрицание позволяет выражать задуманные правила в коде без написания новых функций.
Двойное отрицание
А что, если написать !!isEven(10)? Внезапно, но код сработает. В логике двойное отрицание равносильно отсутствию отрицания:
isEven(10); // true
!isEven(10); // false
!!isEven(10); // trueКомбинирование с && и ||
! можно комбинировать с && и ||. Среди логических операторов у отрицания наивысший приоритет, поэтому оно применяется первым:
!true || true; // (!true) || true => false || true => true
!true && false; // (!true) && false => false && false => falseСкобки меняют порядок вычисления:
!(true || true); // !true => false
!(true && false); // !false => trueПрактический пример — функция проверяет, может ли водитель сесть за руль: нужны права и трезвость:
const canDrive = (hasLicense, isDrunk) => hasLicense && !isDrunk;
console.log(canDrive(true, false)); // => true (есть права, трезвый)
console.log(canDrive(true, true)); // => false (есть права, но пьяный)
console.log(canDrive(false, false)); // => false (нет прав)Законы де Моргана
При работе со сложными логическими выражениями бывает нужно инвертировать их или переписать в эквивалентную, более читаемую форму. Для этого существуют законы де Моргана — два правила, описывающих, как отрицание распределяется по составному выражению:
!(a && b) === !a || !b;
!(a || b) === !a && !b;Первый закон: отрицание конъюнкции равно дизъюнкции отрицаний. Проверим:
!(true && false); // !false => true
!true || !false; // false || true => trueВторой закон: отрицание дизъюнкции равно конъюнкции отрицаний:
!(true || false); // !true => false
!true && !false; // false && true => falseНа практике законы де Моргана помогают упрощать условия. Например, вместо !(isAdmin || isModerator) можно написать !isAdmin && !isModerator — читается как «не администратор и не модератор».
Задание
Напишите две функции:
isPalindrome(str)— возвращаетtrue, если строка является палиндромом (читается одинаково в обоих направлениях).isNotPalindrome(str)— возвращаетtrue, если строка не является палиндромом.
isPalindrome("level"); // => true
isPalindrome("hello"); // => false
isNotPalindrome("level"); // => false
isNotPalindrome("hello"); // => true
// Строки в функции могут быть переданы в любом регистре
// Поэтому сначала приведите строку к нижнему регистру методом .toLowerCase()
isPalindrome("Wow"); // => true
isNotPalindrome("Wow"); // => falseИспользуйте метод .split(''), .reverse(), .join('') для разворота строки.
Полезное
Ваше упражнение проверяется по этим тестам
// @ts-check
import { expect, test } from "vitest";
import f from "./index.js";
test("logical negation", () => {
expect(f("wow")).toBe(false);
expect(f("hexlet")).toBe(true);
expect(f("asdffdsa")).toBe(false);
expect(f("Wow")).toBe(false);
});Решение учителя откроется через:
20:00
