我编写了以下Javascript函数,该函数应在其中一个参数正确时返回true
:
function onlyOne( a, b, c) {
return (a && !b && !c) ||
(b && !a && !c) ||
(c && !a && !b);
}
它可以按预期工作,但在某些情况下返回0
:
EXPECT true:
true = onlyOne( 1, 0, 0)
true = onlyOne( 0, 1, 0)
true = onlyOne( 0, 0, 1)
EXPECT false:
0 = onlyOne( 0, 0, 0)
false = onlyOne( 0, 1, 1)
false = onlyOne( 1, 0, 1)
0 = onlyOne( 1, 1, 0)
false = onlyOne( 1, 1, 1)
为什么在上述两种情况下返回0
而不是false?我看到只有c
为0的两个否定情况,但是我看不出这有什么区别。显然,在这里我不了解Javascript逻辑运算符和/或类型转换。
这里是产生上述输出的完整代码。我正在使用node.js 4.3.0从Windows命令行运行此命令,如果有任何不同的话:
function testOnlyOne( a, b, c) {
result = onlyOne(a, b, c);
console.log("%j = onlyOne( %j, %j, %j)", result, a, b, c);
}
function onlyOne( a, b, c) {
return (a && !b && !c) ||
(b && !a && !c) ||
(c && !a && !b);
}
console.log("\nEXPECT true:");
testOnlyOne( 1, 0, 0);
testOnlyOne( 0, 1, 0);
testOnlyOne( 0, 0, 1);
console.log("\nEXPECT false:");
testOnlyOne( 0, 0, 0);
testOnlyOne( 0, 1, 1);
testOnlyOne( 1, 0, 1);
testOnlyOne( 1, 1, 0);
testOnlyOne( 1, 1, 1);
答案 0 :(得分:1)
因为JavaScript检查伪造和真实值的方式。诸如false
,0
,''
undefined
,null
等之类的值被认为是虚假的(Boolean()
的返回值这些返回值false
中的任何一个,而其他true
,1
,'hi'
,[]
等都是真实的(对于任何返回值,Boolean()
这些回报true
)。
因此,当执行0 && 'a'
之类的指令时,总是会返回0
,因为0
是虚假的,并且&&
运算符在任何值为false之后都不会前进,因为&&
要返回true
的所有值必须是真实的。另一方面,执行诸如true && 'hello' && null
之类的指令将始终返回null
,因为直到null
的所有第一个值都是真实的,因此实际语句解析为null
。
答案 1 :(得分:0)
stackblitz example可能值得一读,以了解js为什么以这种方式处理事情。
由&&或||产生的值运算符不一定是布尔类型。产生的值将始终是两个操作数表达式之一的值。
&&和||得出(确切地)其操作数之一的值:
- 如果A可以强制为false,则A && B返回值A;否则,它将返回B。
- A ||如果可以将A强制为true,则B返回值A。否则,它将返回B。
如果您希望结果为布尔值,则可以使用“ not-not”,例如:!!expression