Programing

JavaScript에 논리적 xor가없는 이유는 무엇입니까?

crosscheck 2020. 5. 18. 21:58
반응형

JavaScript에 논리적 xor가없는 이유는 무엇입니까?


JavaScript에 논리적 xor가없는 이유는 무엇입니까?


JavaScript는 조상을 다시 C로 추적하며 C에는 논리적 XOR 연산자가 없습니다. 주로 유용하지 않기 때문에. Bitwise XOR은 매우 유용하지만 수년간의 프로그래밍에서 논리적 XOR이 필요하지 않았습니다.

부울 변수가 두 개인 경우 다음을 사용하여 XOR을 모방 할 수 있습니다.

if (a != b)

두 개의 임의 변수를 사용 !하면 값을 부울 값으로 강제 변환하고 동일한 트릭을 사용할 수 있습니다.

if (!a != !b)

그래도 꽤 모호하며 분명히 의견이 필요합니다. 실제로이 시점에서 비트 XOR 연산자를 사용할 수도 있지만 내 취향에는 너무 영리합니다.

if (!a ^ !b)

자바 스크립트에는 비트 XOR 연산자가 있습니다 : ^

var nb = 5^9 // = 12

부울과 함께 사용할 수 있으며 결과를 0 또는 1로 제공합니다 (예를 들어 부울로 다시 변환 할 수 있음 result = !!(op1 ^ op2)). 그러나 John이 말했듯이 result = (op1 != op2)이는보다 명확합니다.


Javascript에는 실제 논리 부울 연산자가 없습니다 ( !아주 가깝습니다). 논리 연산자는 걸릴 것 true또는 false피연산자 만 반환 true또는 false.

자바 스크립트 &&||피연산자의 모든 종류를 가지고 (당신이 그들로 공급 무엇이든) 재미 결과의 모든 종류를 반환합니다.

또한 논리 연산자는 항상 두 피연산자의 값을 고려해야합니다.

자바 스크립트 &&||게으른 바로 가기를 가지고 할 수 없습니다 어떤 경우함으로써 부작용 방치 두 번째 피연산자를 평가합니다. 이 동작은 논리 xor로 다시 만들 수 없습니다.


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

그러나이 결과의 실제 값을 사용하여 "실제"논리 연산자가 true 또는 false를 반환했는지 여부를 결정할 수도 있습니다.

이렇게하면 다음과 같은 것을 쓸 수 있습니다

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) {있습니다. 매우 혼란 스럽습니다.


두 부울의 XOR은 단순히 서로 다른지 여부입니다.

Boolean(a) !== Boolean(b)

... 종류가 있습니다 :

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

또는 더 읽기 쉽다 :

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

왜? 던노

자바 스크립트 개발자는 이미 구현 된 다른 논리 연산자로 표현할 수 있으므로 불필요하다고 생각했기 때문입니다.

당신은 낸드와 곤두박질을 할 수 있으며, 그로부터 가능한 모든 다른 논리 연산에 깊은 인상을 줄 수 있습니다.

개인적으로 c 기반 구문 언어를 사용하는 역사적인 이유가 있다고 생각합니다. 제 지식이 없거나 적어도 매우 드문 곳입니다.


예, 다음을 수행하십시오. 부울 A 및 B를 처리한다고 가정하면 다음을 사용하여 JavaScript에서 A XOR B 값을 계산할 수 있습니다

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

이전 줄은 다음과 같습니다.

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

Personally, I prefer xor1 since I have to type less characters. I believe that xor1 is also faster too. It's just performing two calculations. xor2 is performing three calculations.

Visual Explanation ... Read the table bellow (where 0 stands for false and 1 stands for true) and compare the 3rd and 5th columns.

!(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.


Covert to boolean and then perform xor like -

!!a ^ !!b

Convert values into Boolean form then take bitwise XOR. It will help with non-boolean values as well.

Boolean(a) ^ Boolean(b)

Check out:

You can mimic it something like this:

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

How about transforming the result int to a bool with double negation? Not so pretty, but really compact.

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);


In above xor function it will result SIMILAR result as logical xor does not exactly logical xor, means it will result "false for equal values" and "true for different values" with data type matching in consideration.

This xor function will work as actual xor or logical operator, means it will result true or false according to the passing values are truthy or falsy. Use according to your needs

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

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

You use the fact that cond1 xor cond2 is equivalent to 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])}`)
}


The reason there is no logical XOR (^^) is because unlike && and || it does not give any lazy-logic advantage. That is the state of both expressions on the right and left have to be evaluated.


In Typescript (The + changes to numeric value):

value : number = (+false ^ +true)

So:

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

Try this short and easy to understand one

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

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

This will work for any data type

참고URL : https://stackoverflow.com/questions/4540422/why-is-there-no-logical-xor-in-javascript

반응형