Почему в JavaScript нет логического xor?

Почему в JavaScript нет логического xor?

Ответ 1

JavaScript отслеживает свою родословную на C, а C не имеет логического оператора XOR. В основном потому, что это не полезно. Побитовое XOR чрезвычайно полезно, но за все годы программирования мне никогда не нужен логический XOR.

Если у вас есть две логические переменные, вы можете имитировать XOR с помощью:

if (a != b)

С двумя произвольными переменными вы можете использовать !, чтобы принудить их к логическим значениям, а затем использовать один и тот же трюк:

if (!a != !b)

Это довольно неясно, хотя и, безусловно, заслуживает комментария. Действительно, вы могли бы даже использовать побитовый оператор XOR в этот момент, хотя это было бы слишком умно для моего вкуса:

if (!a ^ !b)

Ответ 2

Javascript имеет побитовый оператор XOR: ^

var nb = 5^9 // = 12

Вы можете использовать его с booleans, и он даст результат как 0 или 1 (который вы можете преобразовать обратно в boolean, например result = !!(op1 ^ op2)). Но, как сказал Джон, это эквивалентно result = (op1 != op2), что яснее.

Ответ 3

В Javascript нет реальных логических логических операторов (хотя ! Подходит довольно близко). Логический оператор будет принимать только true или false качестве операндов и будет возвращать только true или false.

В Javascript && и || возьмите всевозможные операнды и верните всевозможные забавные результаты (что бы вы ни вводили в них).

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

В Javascript && и || возьмите ленивый ярлык и не оценивайте второй операнд в некоторых случаях и тем самым пренебрегайте его побочными эффектами. Такое поведение невозможно воссоздать с логическим xor.


a() && b() оценивает a() и возвращает результат, если он ложный. В противном случае он оценивает b() и возвращает результат. Следовательно, возвращаемый результат верен, если оба результата верны, и ложен в противном случае.

a() || b() a() || b() оценивает a() и возвращает результат, если он правдив. В противном случае он оценивает b() и возвращает результат. Следовательно, возвращаемый результат ложен, если оба результата ложны, и истинен в противном случае.

Итак, общая идея - сначала оценить левый операнд. Правильный операнд оценивается только при необходимости. И последнее значение - результат. Этот результат может быть чем угодно. Объекты, числа, строки... что угодно!

Это позволяет писать такие вещи, как

image = image || new Image(); // default to a new Image

или же

src = image && image.src; // only read out src if we have an image

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

Это позволяет писать такие вещи, как

if (typeof image.hasAttribute === 'function' && image.hasAttribute('src')) {

или же

if (image.hasAttribute('alt') || image.hasAttribute('title')) {

Но "логический" оператор xor (^^) всегда должен оценивать оба операнда. Это отличает его от других "логических" операторов, которые оценивают второй операнд только при необходимости. Я думаю, что именно поэтому в Javascript нет "логического" xor, чтобы избежать путаницы.


Так что же должно произойти, если оба операнда ложные? Оба могут быть возвращены. Но только один может быть возвращен. Который из? Первый? Или второй? Моя интуиция подсказывает мне вернуть первые, но обычно "логические" операторы, вычисляющие слева направо, и вернуть последнее оцененное значение. Или, может быть, массив, содержащий оба значения?

И если один операнд является правдивым, а другой - ложным, xor должен возвращать правдивый. Или, может быть, массив, содержащий истинный, чтобы сделать его совместимым с предыдущим случаем?

И, наконец, что должно произойти, если оба операнда истинны? Вы ожидаете что-то ложное. Но нет никаких ложных результатов. Так что операция не должна ничего возвращать. Так может быть undefined или.. пустой массив? Но пустой массив все еще правдив.

При использовании массива вы получите условия вроде if ((a ^^ b).length !== 1) {. Очень запутанно.

Ответ 4

есть... вид:

if( foo ? !bar : bar ) {
  ...
}

или легче читать:

if( ( foo && !bar ) || ( !foo && bar ) ) {
  ...
}

почему? Не знаю.

потому что разработчики javascript считали, что это не нужно, поскольку это может быть выражено другими, уже реализованными логическими операторами.

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

Я лично считаю, что у него есть исторические причины, которые движутся с языков синтаксиса c-языка, где, насколько мне известно, xor отсутствует или, по крайней мере, необычно.

Ответ 5

XOR двух булевых элементов просто отличается от них:

Boolean(a) !== Boolean(b)

Ответ 6

Да, просто выполните следующее. Предполагая, что вы имеете дело с логическими значениями A и B, тогда значение A XOR B можно вычислить в JavaScript, используя следующий

var xor1 = !(a === b);

Предыдущая строка также эквивалентна следующему

var xor2 = (!a !== !b);

Лично я предпочитаю xor1, так как мне приходится вводить меньше символов. Я считаю, что xor1 тоже быстрее. Он просто выполняет два вычисления. xor2 выполняет три вычисления.

Пояснение к Visual... Прочитайте таблицу ниже (где 0 означает false, а 1 означает true) и сравните 3-й и 5-й столбцы.

! (A === B):

| A | B | A XOR B | A === B | !(A === B) |
------------------------------------------
| 0 | 0 |    0    |    1    |      0     |
| 0 | 1 |    1    |    0    |      1     |
| 1 | 0 |    1    |    0    |      1     |
| 1 | 1 |    0    |    1    |      0     |
------------------------------------------

Enjoy.

Ответ 8

Как преобразовать результат int в bool с двойным отрицанием? Не так красиво, но очень компактно.

var state1 = false,
    state2 = true;
    
var A = state1 ^ state2;     // will become 1
var B = !!(state1 ^ state2); // will become true
console.log(A);
console.log(B);

Ответ 9

В приведенной выше функции xor это приведет к результату ПОДОБНЫЙ, поскольку логический xor не является точно логическим xor, означает, что он приведет к "false для равных значений и " true для разных значений с учетом соответствия типов данных.

Эта xor-функция будет работать как фактический оператор xor или логический, означает, что он будет иметь значение true или false в соответствии с переданными значениями Правка или фальшивость strong > . Использование в соответствии с вашими потребностями

function xor(x,y){return true==(!!x!==!!y);}

function xnor(x,y){return !xor(x,y);}

Ответ 10

Скрытый для логического и затем выполнить XOR, как -

!!a ^ !!b

Ответ 11

Преобразуйте значения в логическую форму, затем возьмите битовое XOR. Это поможет и с не булевыми значениями.

Boolean(a) ^ Boolean(b)

Ответ 12

Причина отсутствия логического XOR (^^) заключается в том, что в отличие от && и || это не дает никакого лениво-логического преимущества. То есть состояние обоих выражений справа и слева должно быть оценено.

Ответ 13

В Typescript (+ меняется на числовое значение):

value : number = (+false ^ +true)

Так:

value : boolean = (+false ^ +true) == 1

Ответ 14

Вы используете тот факт, что cond1 xor cond2 эквивалентен cond1 + cond 2 == 1:

let ops = [[false, false],[false, true], [true, false], [true, true]];

function xor(cond1, cond2){
  return cond1 + cond2 == 1;
}

for(op of ops){
  console.log('${op[0]} xor ${op[1]} is ${xor(op[0], op[1])}')
}

Ответ 15

Попробуйте это коротко и легко понять.

function xor(x,y){return true==(x!==y);}

function xnor(x,y){return !xor(x,y);}

Это будет работать для любого типа данных