【问题标题】:Why does function sometimes return 0 and sometimes return false? [duplicate]为什么函数有时返回 0 有时返回 false? [复制]
【发布时间】: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


【解决方案1】:

因为如果 JavaScript 检查虚假和真实值的方式。诸如false0''undefinednull 等值被认为是虚假的(对于任何这些返回 false,返回值 Boolean()),而其他诸如true1'hi'[] 是真实的(Boolean() 的任何返回值 true)。

因此,在执行诸如0 && 'a'之类的指令时,将始终返回0,因为0是假的,而&&运算符在任何值为假后都不会前进,因为&&要返回@ 987654339@ 应用它的所有值都必须是真实的。另一方面,执行诸如true && 'hello' && null 之类的指令将始终返回null,因为直到null 的所有第一个值都是真实的,因此实际语句解析为null

【讨论】:

    【解决方案2】:

    This blog post 可能值得一读,以了解 js 以这种方式处理事情的原因。

    && 或 || 产生的值运算符不一定是布尔类型。生成的值将始终是两个操作数表达式之一的值。

    && 和 ||导致(恰好)它们的操作数之一的值:

    • 如果 A 可以强制为 false,则 A && B 返回值 A;否则,它返回 B。
    • 一个||如果 A 可以强制为真,则 B 返回值 A;否则,它返回 B。

    如果您希望结果为布尔值,您可以使用“not-not”,如下所示:!!expression

    【讨论】:

    • 谢谢!博客文章非常好。我假设 && 和 ||像在 C 或 Java 中一样工作......
    • 这种行为更类似于 python,如果有的话。 IMO,js 与 Java 或 C 几乎没有共同之处。可能还值得检查不同类型在 if(x) if(!x) if(x==null) 等表达式中的工作方式
    猜你喜欢
    • 2021-03-23
    • 2015-06-21
    • 2017-01-07
    • 2016-03-29
    • 2017-06-20
    • 2015-06-22
    • 1970-01-01
    • 2021-12-30
    • 2018-11-09
    相关资源
    最近更新 更多