Почему в JavaScript нет логического xor?
javascript
xor
logical-operators
DarkLightA
источник
источник
!=
том, что вы не можете сделать то же самоеa ^= b
, потому чтоa !== b
это просто оператор строгого неравенства .В JavaScript есть побитовый оператор XOR: ^
Вы можете использовать его с логическими значениями, и он даст результат в виде 0 или 1 (например, вы можете конвертировать обратно в логическое значение
result = !!(op1 ^ op2)
). Но, как сказал Джон, это эквивалентноresult = (op1 != op2)
, что более понятно.источник
true^true
0 иfalse^true
1||
и&&
может использоваться в качестве логических операторов для небулевых (например,5 || 7
возвращает истинное значение,"bob" && null
возвращает ложное значение), но^
не может. Например,5 ^ 7
равно 2, что является правдой.(true ^ false) !== true
это делает его раздражающим в библиотеках, которые требуют фактических логических значенийa ^= true
переключение логических значений, и оно не работает на некоторых машинах, таких как телефоны.В Javascript нет реальных логических логических операторов (хотя это
!
довольно близко). Логический оператор будет принимать толькоtrue
илиfalse
как операнды и будет только возвращатьtrue
илиfalse
.В Javascript
&&
и||
принимайте всевозможные операнды и возвращайте всевозможные забавные результаты (что бы вы ни вводили в них).Также логический оператор всегда должен учитывать значения обоих операндов.
В Javascript
&&
и||
ленивый ярлык взять и не оценивать второй операнд в определенных случаях и тем самым пренебрегать его побочными эффектами. Такое поведение невозможно воссоздать с логическим xor.a() && b()
оцениваетa()
и возвращает результат, если он ложный. В противном случае он оцениваетb()
и возвращает результат. Следовательно, возвращаемый результат верен, если оба результата верны, и неверен в противном случае.a() || b()
оцениваетa()
и возвращает результат, если он правдив. В противном случае он оцениваетb()
и возвращает результат. Следовательно, возвращаемый результат ложен, если оба результата ложны, и истинен в противном случае.Таким образом, общая идея - сначала оценить левый операнд. Правильный операнд оценивается только при необходимости. И последнее значение - результат. Этот результат может быть чем угодно. Объекты, числа, строки ... что угодно!
Это позволяет писать такие вещи, как
или
Но значение истинности этого результата также можно использовать для определения, вернул ли бы «реальный» логический оператор истину или ложь.
Это позволяет писать такие вещи, как
или
Но «логический» оператор xor (
^^
) всегда должен оценивать оба операнда. Это отличает его от других «логических» операторов, которые оценивают второй операнд только при необходимости. Я думаю, именно поэтому в Javascript нет «логического» xor, чтобы избежать путаницы.Так что же должно произойти, если оба операнда ложные? Оба могут быть возвращены. Но только один может быть возвращен. Который из? Первый? Или второй? Моя интуиция подсказывает мне вернуть первые, но обычно «логические» операторы, вычисленные слева направо, и вернуть последнее оцененное значение. Или, может быть, массив, содержащий оба значения?
И если один операнд является правдивым, а другой - ложным, xor должен возвращать правдивый. Или, может быть, массив, содержащий истинный, чтобы сделать его совместимым с предыдущим случаем?
И, наконец, что должно произойти, если оба операнда истинны? Вы ожидаете чего-то ложного. Но нет никаких ложных результатов. Так что операция не должна ничего возвращать. Так может
undefined
или .. пустой массив? Но пустой массив все еще правдив.При использовании массива вы получите такие условия, как
if ((a ^^ b).length !== 1) {
. Очень запутанно.источник
XOR двух логических выражений заключается просто в том, отличаются ли они, поэтому:
источник
Преобразуйте значения в логическую форму, затем возьмите побитовый XOR. Это поможет и с не булевыми значениями.
источник
Скрытый для логического, а затем выполнить XOR, как -
источник
!!a ^ !!b
эквивалентно!a ^ !b
. Можно приводить аргументы относительно того, какой из них легче читать.есть ... вроде:
или проще читать:
Зачем? Не знаю.
потому что разработчики javascript думали, что это будет ненужным, поскольку это может быть выражено другими, уже реализованными, логическими операторами.
вы также можете просто получить nand, вот и все, вы можете произвести впечатление на любую другую логическую операцию из этого.
Я лично думаю, что у него есть исторические причины, которые берут начало от языков синтаксиса на основе c, где, насколько мне известно, xor отсутствует или, по крайней мере, крайне необычен.
источник
Да, просто сделай следующее. Предполагая, что вы имеете дело с логическими значениями A и B, тогда значение XOR B можно вычислить в JavaScript с помощью следующего
Предыдущая строка также эквивалентна следующей
Лично я предпочитаю xor1, поскольку мне приходится печатать меньше символов. Я считаю, что xor1 тоже быстрее. Он просто выполняет два вычисления. xor2 выполняет три вычисления.
Визуальное объяснение ... Прочитайте приведенную ниже таблицу (где 0 обозначает ложь, а 1 обозначает истину) и сравнивает 3-й и 5-й столбцы.
! (A === B):
Наслаждаться.
источник
var xor1 = !(a === b);
такое же какvar xor1 = a !== b;
!(2 === 3)
естьtrue
, но2
и3
являются truthy так2 XOR 3
должно бытьfalse
.Проверять, выписываться:
Вы можете имитировать это примерно так:
источник
Как насчет преобразования результата int в bool с двойным отрицанием? Не очень красиво, но очень компактно.
источник
B = ((!state1)!==(!state2))
B =!!(!state1 ^ !state2);
Кроме того, почему так много скобок?B = !state1 !== !state2;
Или вы можете даже отбросить отрицание:B = state1 !== state2;
state1 !== state2
, тогда вам не нужно выполнять какое-либо приведение, поскольку!==
это логический оператор, а не побитовый.12 !== 4
это правда,'xy' !== true
это тоже правда. Если бы вы использовали!=
вместо!==
, то вам придется делать кастинг.!==
и!=
всегда логичен ... не уверен, какое различие вы там делаете, это не проблема. Проблема в том, что оператор XOR, который мы хотим , действительно является выражением(Boolean(state1) !== Boolean(state2))
. Для логических значений «xy», 12, 4 иtrue
все являются истинными значениями, и их следует преобразовать вtrue
. так("xy" XOR true)
должно бытьfalse
, но("xy" !== true)
вместо этогоtrue
, как вы указываете. Так что!==
или!=
(оба) эквивалентны «логическому XOR» тогда и только тогда, когда вы преобразуете их аргументы в логические значения перед применением.В приведенной выше функции XOR это приведет ПОДОБНОМУ результату, так как логический xor не совсем логический xor, означает, что это приведет к «false для равных значений» и «true для разных значений» с учетом соответствия типов данных.
Эта функция xor будет работать как фактический xor или логический оператор , это означает, что она будет иметь значение true или false в соответствии с передаваемыми значениями true или false . Используйте в соответствии с вашими потребностями
источник
(!!x) === (!!y)
. Разница в приведении к логическому.'' === 0
ложно, аxnor('', 0)
верно.В Typescript (+ меняется на числовое значение):
Так:
источник
!!(false ^ true)
отлично работает с логическими значениями. В машинописи + требуется, чтобы сделать его действительным!!(+false ^ +true)
.cond1 xor cond2
эквивалентноcond1 + cond 2 == 1
:Вот доказательство:
источник
Причина отсутствия логического XOR (^^) в том, что в отличие от && и || это не дает никакого ленивого логического преимущества. Это состояние обоих выражений справа и слева должны быть оценены.
источник
Вот альтернативное решение, которое работает с 2+ переменными и обеспечивает счет в качестве бонуса.
Вот более общее решение для имитации логического XOR для любых значений true / falsey, как если бы вы имели оператор в стандартных операторах IF:
Мне это нравится по той причине, что он также отвечает «Сколько из этих переменных являются правдивыми?», Поэтому я обычно предварительно сохраняю этот результат.
А для тех, кто хочет строго проверять булево-TRUE поведение xor, просто выполните:
Если вам не важен счет, или если вы заботитесь об оптимальной производительности: просто используйте побитовый xor для значений, приведенных к булевому, для истинного / ложного решения:
источник
Привет, я нашел это решение, чтобы сделать и XOR на JavaScript и TypeScript.
источник
Попробуйте это коротко и легко понять
Это будет работать для любого типа данных
источник
true == someboolean
не нужно, так что на самом деле вы заключаете в функцию строгое неравное.