为什么JavaScript中没有逻辑异或?
为什么JavaScript中没有逻辑异或?
JavaScript将其祖先追溯回C,而C没有逻辑XOR运算符。 主要是因为它没用。 按位异或非常有用,但在我所有的编程年代中,我从来都不需要逻辑异或。
如果你有两个布尔变量,你可以模仿XOR:
if (a != b)
用两个任意的变量你可以使用!
将它们强制为布尔值,然后使用相同的技巧:
if (!a != !b)
这很不明显,但肯定值得评论。 事实上,你甚至可以在这一点上使用按位XOR运算符,虽然这对我的口味来说太聪明了:
if (!a ^ !b)
Javascript有一个按位XOR运算符:^
var nb = 5^9 // = 12
您可以将它与布尔值一起使用,并将结果作为0或1(您可以将其转换回布尔值,例如result = !!(op1 ^ op2)
)。 但正如约翰所说,它相当于result = (op1 != op2)
,这更清楚。
Javascript中没有真正的逻辑布尔操作符(尽管!
非常接近)。 逻辑运算符只会将true
或false
作为操作数,只会返回true
或false
。
在Javascript &&
和||
采取各种各样的操作数,并返回各种有趣的结果(无论你喂给他们)。
逻辑运算符也应始终考虑两个操作数的值。
在Javascript &&
和||
采取懒惰的捷径,并且在某些情况下不要评估第二个操作数,从而忽略其副作用。 这种行为是不可能用逻辑xor重新创建的。
a() && b()
评估a()
并返回结果,如果它是虚假的。 否则,它评估b()
并返回结果。 因此,如果两个结果都是真的,则返回的结果是真实的,否则就是虚假的。
a() || b()
a() || b()
评估a()
并返回结果。 否则,它评估b()
并返回结果。 因此,如果两个结果都是错误的,则返回的结果是虚假的,否则就是truthy。
所以总的想法是首先评估左操作数。 只有在必要时才会评估右操作数。 最后一个值是结果。 这个结果可以是任何东西。 对象,数字,字符串..不管!
这可以写出类似的东西
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,以避免混淆。
那么如果两个操作数都是虚假的,会发生什么? 两者都可以退回。 但只有一个可以退回。 哪一个? 第一个? 还是第二个? 我的直觉告诉我要返回第一个但通常是“逻辑”的操作符从左到右评估并返回最后一个评估值。 或者可能是一个包含两个值的数组?
如果一个操作数是真的,而另一个操作数是假的,则一个操作数应该返回真值。 或者可能是一个包含truthy的数组,以使其与之前的情况兼容?
最后,如果两个操作数都是真的会发生什么? 你会期望一些虚假的东西。 但是没有任何错误的结果。 所以操作不应该返回任何东西。 所以也许undefined
或..一个空阵列? 但是一个空阵列仍然很糟糕。
采用数组的方法,你最终会得到像if ((a ^^ b).length !== 1) {
。 很混乱。