为什么 JavaScript 中没有逻辑异或?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4540422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is there no logical xor in JavaScript?
提问by DarkLightA
Why is there no logical xor in JavaScript?
为什么 JavaScript 中没有逻辑异或?
回答by John Kugelman
JavaScript traces its ancestry back to C, and C does not have a logical XOR operator. Mainly because it's not useful. Bitwise XOR is extremely useful, but in all my years of programming I have never needed a logical XOR.
JavaScript 的祖先可以追溯到 C,而 C 没有逻辑 XOR 运算符。主要是因为它没有用。按位异或非常有用,但在我多年的编程生涯中,我从未需要逻辑异或。
If you have two boolean variables you can mimic XOR with:
如果您有两个布尔变量,您可以通过以下方式模拟 XOR:
if (a != b)
With two arbitrary variables you could use !
to coerce them to boolean values and then use the same trick:
您可以使用两个任意变量将!
它们强制为布尔值,然后使用相同的技巧:
if (!a != !b)
That's pretty obscure though and would certainly deserve a comment. Indeed, you could even use the bitwise XOR operator at this point, though this would be far too clever for my taste:
不过,这相当晦涩难懂,当然值得评论。实际上,此时您甚至可以使用按位异或运算符,尽管这对我的口味来说太聪明了:
if (!a ^ !b)
回答by Pikrass
Javascript has a bitwise XOR operator : ^
Javascript 有一个按位异或运算符:^
var nb = 5^9 // = 12
You can use it with booleans and it will give the result as a 0 or 1 (which you can convert back to boolean, e.g. result = !!(op1 ^ op2)
). But as John said, it's equivalent to result = (op1 != op2)
, which is clearer.
您可以将它与布尔值一起使用,它会将结果作为 0 或 1(您可以将其转换回布尔值,例如result = !!(op1 ^ op2)
)。但正如约翰所说,它相当于result = (op1 != op2)
,更清楚。
回答by Robert
There are no real logical boolean operators in Javascript (although !
comes quite close). A logical operator would only take true
or false
as operands and would only return true
or false
.
Javascript 中没有真正的逻辑布尔运算符(尽管!
非常接近)。逻辑运算符只会将true
orfalse
作为操作数,并且只会返回true
or false
。
In Javascript &&
and ||
take all kinds of operands and return all kinds of funny results (whatever you feed into them).
在 Javascript 中&&
,||
使用各种操作数并返回各种有趣的结果(无论你输入什么)。
Also a logical operator should always take the values of both operands into account.
此外,逻辑运算符应始终考虑两个操作数的值。
In Javascript &&
and ||
take a lazy shortcut and do notevaluate the second operand in certain cases and thereby neglect its side effects. This behavior is impossible to recreate with a logical xor.
在 Javascript 中&&
并||
采取惰性快捷方式,在某些情况下不评估第二个操作数,从而忽略其副作用。这种行为不可能用逻辑异或重新创建。
a() && b()
evaluates a()
and returns the result if it's falsy.
Otherwise it evaluates b()
and returns the result. Therefore the returned result is truthy if both results are truthy, and falsy otherwise.
a() && b()
a()
如果结果为假,则计算并返回结果。否则,它会评估b()
并返回结果。因此,如果两个结果都为真,则返回的结果为真,否则为假。
a() || b()
evaluates a()
and returns the result if it's truthy.
Otherwise it evaluates b()
and returns the result. Therefore the returned result is falsy if both results are falsy, and truthy otherwise.
a() || b()
a()
如果结果为真,则计算并返回结果。否则,它会评估b()
并返回结果。因此,如果两个结果都为假,则返回的结果为假,否则为真。
So the general idea is to evaluate the left operand first. The right operand only gets evaluated if necessary. And the last value is the result. This result can be anything. Objects, numbers, strings .. whatever!
所以一般的想法是先评估左操作数。仅在必要时评估正确的操作数。最后一个值是结果。这个结果可以是任何东西。对象、数字、字符串……随便!
This makes it possible to write things like
这使得编写类似的东西成为可能
image = image || new Image(); // default to a new Image
or
或者
src = image && image.src; // only read out src if we have an image
But the truth value of this result can also be used to decide if a "real" logical operator would have returned true or false.
但是这个结果的真值也可以用来决定一个“真正的”逻辑运算符是否会返回真或假。
This makes it possible to write things like
这使得编写类似的东西成为可能
if (typeof image.hasAttribute === 'function' && image.hasAttribute('src')) {
or
或者
if (image.hasAttribute('alt') || image.hasAttribute('title')) {
But a "logical" xor operator (^^
) would always have to evaluate both operands. This makes it different to the other "logical" operators which evaluate the second operand only if necessary. I think this is why there is no "logical" xor in Javascript, to avoid confusion.
但是“逻辑”异或运算符 ( ^^
) 将始终必须评估两个操作数。这使它与其他“逻辑”运算符不同,后者仅在必要时评估第二个操作数。我认为这就是 Javascript 中没有“逻辑”xor 以避免混淆的原因。
So what should happen if both operands are falsy? Both could be returned. But only one can be returned. Which one? The first one? Or the second one? My intuition tells me to return the first but usually "logical" operators evaluate from left to right and return the last evaluated value. Or maybe an array containing both values?
那么如果两个操作数都是假的,会发生什么呢?两者都可以退货。但是只能退货。哪一个?第一个?还是第二个?我的直觉告诉我返回第一个但通常是“逻辑”运算符从左到右求值并返回最后一个求值值。或者可能是一个包含两个值的数组?
And if one operand is truthy and the other operand is falsy, an xor should return the truthy one. Or maybe an array containing the truthy one, to make it compatible with the previous case?
如果一个操作数为真而另一个操作数为假,则异或应返回真值。或者可能是一个包含真实数组的数组,以使其与前一种情况兼容?
And finally, what should happen if both operands are truthy? You would expect something falsy. But there are no falsy results. So the operation shouldn't return anything. So maybe undefined
or .. an empty array? But an empty array is still truthy.
最后,如果两个操作数都为真,会发生什么?你会期待一些虚假的东西。但是没有错误的结果。所以操作不应该返回任何东西。所以也许undefined
还是..一个空数组?但是空数组仍然是真实的。
Taking the array approach you would end up with conditions like if ((a ^^ b).length !== 1) {
. Very confusing.
采用数组方法,您最终会遇到类似if ((a ^^ b).length !== 1) {
. 非常混淆。
回答by DomQ
The XOR of two booleans is simply whether they are different, therefore:
两个布尔值的异或只是它们是否不同,因此:
Boolean(a) !== Boolean(b)
回答by Aman Kaushal
Convert values into Boolean form then take bitwise XOR. It will help with non-boolean values as well.
将值转换为布尔形式,然后进行按位异或。它也将有助于非布尔值。
Boolean(a) ^ Boolean(b)
回答by toyeca
Covert to boolean and then perform xor like -
转换为布尔值,然后执行 xor 之类的 -
!!a ^ !!b
回答by The Surrican
there is... sort of:
有......有点:
if( foo ? !bar : bar ) {
...
}
or easier to read:
或更容易阅读:
if( ( foo && !bar ) || ( !foo && bar ) ) {
...
}
why? dunno.
为什么?不知道。
because javascript developers thought it would be unnecessary as it can be expressed by other, already implemented, logical operators.
因为 javascript 开发人员认为它是不必要的,因为它可以由其他已经实现的逻辑运算符表示。
you could as well just have gon with nand and thats it, you can impress every other possible logical operation from that.
您也可以只使用 nand,仅此而已,您可以从中留下所有其他可能的逻辑操作。
i personally think it has historical reasons that drive from c-based syntax languages, where to my knowledge xor is not present or at least exremely uncommon.
我个人认为它有来自基于 c 的语法语言的历史原因,据我所知 xor 不存在或至少非常罕见。
回答by asiby
Yes, Just do the following. Assuming that you are dealing with booleans A and B, then A XOR B value can be calculated in JavaScript using the following
是的,只需执行以下操作。假设您正在处理布尔值 A 和 B,那么可以使用以下代码在 JavaScript 中计算 A XOR B 值
var xor1 = !(a === b);
The previous line is also equivalent to the following
上一行也等效于以下内容
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.
就个人而言,我更喜欢 xor1,因为我必须输入较少的字符。我相信 xor1 也更快。它只是执行两个计算。xor2 正在执行三个计算。
Visual Explanation ... Read the table bellow (where 0 stands for false and 1 stands for true) and compare the 3rd and 5th columns.
视觉解释...阅读下表(其中 0 代表假,1 代表真)并比较第 3 列和第 5 列。
!(A === B):
!(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.
享受。
回答by Sarfraz
Check out:
查看:
You can mimic it something like this:
你可以像这样模仿它:
if( ( foo && !bar ) || ( !foo && bar ) ) {
...
}
回答by Lajos Meszaros
How about transforming the result intto a boolwith double negation? Not so pretty, but really compact.
将结果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);