【发布时间】:2018-07-20 20:30:48
【问题描述】:
我编写了以下 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);
【问题讨论】:
-
JavaScript
&&和||运算符不一定返回布尔值。 -
如果第一个参数是 0,这是假的,则不需要执行以下
&&可能会将其变为假,因此它返回 0。如果第一个参数是 || 的 1,则不需要进行以下检查。这就是所谓的短路逻辑。 -
将结果强制转换为布尔值的一种常见方法是双键 (
!!),如return !! ( (a && !b && !c) || (b && !a && !c) || (c && !a && !b) ),它将始终产生一个布尔类型 -
jsfiddle.net/jmx543ae 作为评论的替代方法,因为,的确,这个问题与重构无关
标签: javascript node.js