Joh*_*ica 344

JavaScript将其祖先追溯到C,而C没有逻辑XOR运算符.主要是因为它没用.Bitwise XOR非常有用,但在我多年的编程中,我从未需要逻辑XOR.

如果你有两个布尔变量,你可以模仿XOR:

if (a != b)
Run Code Online (Sandbox Code Playgroud)

使用两个任意变量可以!将它们强制转换为布尔值,然后使用相同的技巧:

if (!a != !b)
Run Code Online (Sandbox Code Playgroud)

这虽然很模糊,但肯定值得评论.实际上,你甚至可以在这一点上使用按位XOR运算符,尽管这对我来说太聪明了:

if (!a ^ !b)
Run Code Online (Sandbox Code Playgroud)

  • 只要你已经有两个布尔变量,“a”和“b”,XOR确实是多余的。但当人们已经有了布尔变量时,通常不需要布尔运算。你永远不会做`const a = foo == bar; if (a == true) { console.log("foo=bar"); 布尔运算的要点是允许简单的内联测试,由编译器优化,而无需定义无关变量的开销。 (3认同)

Pik*_*ass 77

Javascript有一个按位XOR运算符:^

var nb = 5^9 // = 12
Run Code Online (Sandbox Code Playgroud)

您可以将它与布尔值一起使用,它将结果显示为0或1(您可以将其转换回布尔值,例如result = !!(op1 ^ op2)).但正如约翰所说,它相当于result = (op1 != op2),更清楚.

  • 您可以将其用作逻辑xor.`true ^ true`为0,`false ^ true`为1. (62认同)
  • 这是按位XOR,不是逻辑异或 (24认同)
  • @Pikrass 您可以将它用作逻辑运算符 *on booleans*,但不能用于其他类型。`||` 和 `&&` 可以用作非布尔值的逻辑运算符(例如,`5 || 7` 返回一个真值,`"bob" && null` 返回一个假值)但 `^` 不能。例如,`5 ^ 7` 等于 2,这是真的。 (12认同)
  • @Pikrass但遗憾的是,`(true ^ false)!== true`,这使得它对需要实际布尔值的库感到烦恼 (8认同)
  • @Pikrass 您永远不应该将它用作布尔值的逻辑运算符,因为实现取决于操作系统。我正在使用某种`a ^= true` 来切换布尔值,但它在某些机器(如手机)上失败了。 (2认同)
  • @cronvel 当然,只是有时,您尝试缩短超长路径,例如`myObj.collection[index].someImportantFlag = !myObj.collection[index].someImportantFlag` 所以用`^= 编写它更方便真的`。我再也不会被诱惑了:) (2认同)

Rob*_*ert 29

Javascript中没有真正的逻辑布尔运算符(尽管!非常接近).逻辑运算符只接受truefalse作为操作数,并且只返回truefalse.

在Javascript中&&||采取各种操作数并返回各种有趣的结果(无论你喂它们什么).

逻辑运算符也应始终考虑两个操作数的值.

在Javascript中,&&||采取懒惰的快捷方式,并在某些情况下评估第二个操作数,从而忽略其副作用.使用逻辑xor无法重新创建此行为.


a() && b()a()如果它是假的,则评估并返回结果.否则,它会计算b()并返回结果.因此,如果两个结果都是真实的,那么返回的结果是真实的,否则就是假的.

a() || b()评估a()并返回结果,如果它是真的.否则,它会计算b()并返回结果.因此,如果两个结果都是假的,则返回的结果是假的,否则就是真实的.

所以一般的想法是首先评估左操作数.只有在必要时才会评估右操作数.最后一个值就是结果.这个结果可以是任何东西.对象,数字,字符串..无论如何!

这使得编写像这样的东西成为可能

image = image || new Image(); // default to a new Image
Run Code Online (Sandbox Code Playgroud)

要么

src = image && image.src; // only read out src if we have an image
Run Code Online (Sandbox Code Playgroud)

但是,此结果的真值也可用于确定"真实"逻辑运算符是返回true还是false.

这使得编写像这样的东西成为可能

if (typeof image.hasAttribute === 'function' && image.hasAttribute('src')) {
Run Code Online (Sandbox Code Playgroud)

要么

if (image.hasAttribute('alt') || image.hasAttribute('title')) {
Run Code Online (Sandbox Code Playgroud)

但是"逻辑"xor运算符(^^)总是必须评估两个操作数.这使得它与仅在必要时评估第二操作数的其他"逻辑"运算符不同.我认为这就是Javascript中没有"逻辑"xor的原因,以避免混淆.


那么如果两个操作数都是假的会发生什么呢?两者都可以归还.但只有一个可以返回.哪一个?第一个?还是第二个?我的直觉告诉我返回第一个但通常是"逻辑"的运算符从左到右评估并返回最后一个评估值.或者可能包含两个值的数组?

如果一个操作数是真实的而另一个操作数是假的,那么xor应该返回真正的操作数.或者也许是一个包含真实数组的数组,以使其与之前的情况兼容?

最后,如果两个操作数都是真的会发生什么?你会期待一些虚假的东西.但没有虚假的结果.所以操作不应该返回任何东西.也许undefined或者......一个空阵列?但是一个空阵列仍然是真实的.

采用阵列方法,你最终会遇到类似的情况if ((a ^^ b).length !== 1) {.很混乱.

  • @Percy AND/&&不评估第二个操作数,如果第一个操作数为false.它只会在找到假值之前评估操作数. (9认同)
  • 那天我一定是在抽烟. (4认同)

Dom*_*omQ 12

两个布尔值的XOR只是它们是否不同,因此:

Boolean(a) !== Boolean(b)
Run Code Online (Sandbox Code Playgroud)

  • 我不得不使用这个解决方案,因为当你尝试将“^”与布尔值一起使用时,TypeScript 会抱怨。 (2认同)

The*_*can 9

有......有点:

if( foo ? !bar : bar ) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

或更容易阅读:

if( ( foo && !bar ) || ( !foo && bar ) ) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

为什么?不知道.

因为javascript开发人员认为它是不必要的,因为它可以由其他已经实现的逻辑运算符表示.

你也可以和nand一起使用,这就是它,你可以从中得到其他可能的逻辑操作.

我个人认为它有历史原因,从基于c的语法语言驱动,我知道xor不存在或至少非常罕见.


小智 8

隐式转换为布尔值,然后执行xor,例如-

!!a ^ !!b
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`!!a ^ !!b` 等同于 `!a ^ !b`。可以就哪个更容易阅读进行争论。 (4认同)

asi*_*iby 7

是的,请执行以下操作.假设您正在处理布尔值A和B,则可以使用以下方法在JavaScript中计算A XOR B值

var xor1 = !(a === b);
Run Code Online (Sandbox Code Playgroud)

前一行也等同于以下内容

var xor2 = (!a !== !b);
Run Code Online (Sandbox Code Playgroud)

就个人而言,我更喜欢xor1,因为我必须键入较少的字符.我相信xor1也更快.它只是执行两次计算.xor2正在执行三次计算.

视觉解释...阅读下表(其中0代表假,1代表真),并比较第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     |
------------------------------------------
Run Code Online (Sandbox Code Playgroud)

请享用.

  • `var xor1 =!(a === b);`与`var xor1 = a!== b;相同;` (6认同)
  • 如果您仔细阅读了我的信息,您会注意到我写了“假设您正在处理布尔A和B ...”。 (2认同)

小智 7

将值转换为布尔形式,然后进行按位XOR。它也将有助于非布尔值。

Boolean(a) ^ Boolean(b)
Run Code Online (Sandbox Code Playgroud)


Sar*_*raz 5

查看:

您可以像这样模仿它:

if( ( foo && !bar ) || ( !foo && bar ) ) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

  • 嘿,如果他们在JavaScript中添加了逻辑XOR运算符,它将使代码示例看起来更加简洁。 (2认同)