Answers:
Javascript具有按位XOR运算符:^
var nb = 5^9 // = 12
您可以将其与布尔值一起使用,并且结果将为0或1(您可以将其转换回布尔值,例如result = !!(op1 ^ op2)
)。但是正如约翰所说,它等效于result = (op1 != op2)
,这更加清楚。
true^true
是0,并且false^true
是1
||
并&&
可用作非布尔值的逻辑运算符(例如,5 || 7
返回真实值,"bob" && null
返回伪值),但^
不能。例如,5 ^ 7
等于2,这是事实。
(true ^ false) !== true
,这使需要实际布尔值的库变得烦人
a ^= true
来切换布尔值,但在某些机器(例如电话)上,它却失败了。
Javascript中没有真正的逻辑布尔运算符(尽管!
非常接近)。逻辑运算符只能采用true
或false
作为操作数,并且只能返回true
或false
。
使用Javascript &&
并||
获取各种操作数,并返回各种有趣的结果(无论您输入什么结果)。
同样,逻辑运算符应始终考虑两个操作数的值。
在Javascript中&&
,||
采用懒惰的快捷方式,在某些情况下不要评估第二个操作数,从而忽略了它的副作用。使用逻辑异或无法重新创建此行为。
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应该返回真实的一个。还是包含真值的数组,以使其与前面的情况兼容?
最后,如果两个操作数均为真该怎么办?你会期望一些虚假的东西。但是,没有虚假的结果。因此,该操作不应返回任何内容。那么,也许undefined
还是..一个空数组?但是,空数组仍然是事实。
采用数组方法,最终会遇到类似的情况if ((a ^^ b).length !== 1) {
。非常混乱。
将值转换为布尔形式,然后进行按位XOR。它也将有助于非布尔值。
Boolean(a) ^ Boolean(b)
有...一种:
if( foo ? !bar : bar ) {
...
}
或更容易阅读:
if( ( foo && !bar ) || ( !foo && bar ) ) {
...
}
为什么?不知道。
因为javascript开发人员认为这是不必要的,因为它可以由其他已经实现的逻辑运算符表示。
您也可以仅将nand和gon结合起来,就可以从中打动其他所有可能的逻辑运算。
我个人认为,这是有历史原因的,其原因是基于C的语法语言,据我所知,xor不存在或至少极为罕见。
是的,只需执行以下操作。假设您正在处理布尔A和B,则可以使用以下代码在JavaScript中计算XOR B值
var xor1 = !(a === b);
上一行也等效于以下内容
var xor2 = (!a !== !b);
就个人而言,我更喜欢xor1,因为我必须键入更少的字符。我相信xor1也会更快。它仅执行两个计算。xor2正在执行三个计算。
视觉说明...阅读下表(其中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 |
------------------------------------------
请享用。
var xor1 = !(a === b);
与var xor1 = a !== b;
!(2 === 3)
是true
,但是2
和3
是真实的,2 XOR 3
应该这样false
。
如何将结果int转换为具有双重否定的布尔值?不那么漂亮,但确实很紧凑。
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);
B = ((!state1)!==(!state2))
B =!!(!state1 ^ !state2);
为何还有这么多括号?B = !state1 !== !state2;
或者,您甚至可以放弃否定的条件:B = state1 !== state2;
state1 !== state2
,那么您不需要在那里进行任何转换,因为!==
它是逻辑运算符,而不是按位运算。12 !== 4
是真的'xy' !== true
也是如此。如果要使用!=
而不是!==
,则必须进行强制转换。
!==
,并!=
始终是布尔......不知道你正在做的区别有应该是,这是绝对没有问题的。问题是我们想要的XOR运算符实际上是表达式(Boolean(state1) !== Boolean(state2))
。对于布尔值,“ xy”,true
12、4 和均为真实值,应转换为true
。所以("xy" XOR true)
应该是false
,但是("xy" !== true)
是不是true
,正如你指出。因此,!==
或仅当您在应用之前将其参数转换为布尔值时,!=
(两者)都等同于“逻辑XOR” 。
在上面的xor函数中,由于逻辑xor与逻辑xor并不完全相同,因此将得出类似的结果,这意味着在考虑数据类型匹配的情况下,它将得出“相等值为false”和“不同值为true”。
此xor函数将用作实际的xor或逻辑运算符,这意味着根据传递的值是true还是falsy,它将得出 true或false 。根据您的需要使用
function xor(x,y){return true==(!!x!==!!y);}
function xnor(x,y){return !xor(x,y);}
(!!x) === (!!y)
。区别在于转换为布尔值。'' === 0
是错误的,xnor('', 0)
而是真实的。
在打字稿中(“ +”更改为数值):
value : number = (+false ^ +true)
所以:
value : boolean = (+false ^ +true) == 1
!!(false ^ true)
。在打字稿中,+必须使其有效!!(+false ^ +true)
。
这是一个使用2个以上变量并提供计数作为奖励的替代解决方案。
这是一个更通用的解决方案,可以为任何真值/假值模拟逻辑XOR,就像在标准IF语句中使用运算符一样:
const v1 = true;
const v2 = -1; // truthy (warning, as always)
const v3 = ""; // falsy
const v4 = 783; // truthy
const v5 = false;
if( ( !!v1 + !!v2 + !!v3 + !!v4 + !!v5 ) === 1 )
document.write( `[ ${v1} XOR ${v2} XOR "${v3}" XOR ${v4} XOR ${v5} ] is TRUE!` );
else
document.write( `[ ${v1} XOR ${v2} XOR "${v3}" XOR ${v4} XOR ${v5} ] is FALSE!` );
我之所以喜欢它,是因为它还会回答“这些变量中有多少是真实的?”,因此我通常会预先存储该结果。
对于那些想要严格的布尔-真xor检查行为的人,只需执行以下操作:
if( ( ( v1===true ) + ( v2===true ) + ( v3===true ) + ( v4===true ) + ( v5===true ) ) === 1 )
// etc.
如果您不关心计数,或者您不关心最佳性能:只需对强制为布尔值的值使用按位异或,即可得到真假的解决方案:
if( !!v1 ^ !!v2 ^ !!v3 ^ !!v4 ^ !!v5 )
// etc.
嘿,我找到了这个解决方案,可以在JavaScript和TypeScript上进行XOR。
if( +!!a ^ +!!b )
{
//This happens only when a is true and b is false or a is false and b is true.
}
else
{
//This happens only when a is true and b is true or a is false and b is false
}
试试这个简短易懂的
function xor(x,y){return true==(x!==y);}
function xnor(x,y){return !xor(x,y);}
这适用于任何数据类型
true == someboolean
不是必需的,因此,实际上,您要做的就是将严格的不等于包装到函数中。
!=
是您不能做与相同的操作a ^= b
,因为a !== b
它只是严格的不等式运算符。