【问题标题】:JavaScript truthiness in boolean to numbers comparison布尔数字比较中的 JavaScript 真实性
【发布时间】:2011-10-02 05:00:57
【问题描述】:

我是 JavaScript 新手,我正在尝试从 Internet 资源中学习它。虽然我知道会有大量 cr*p 材料,但大多数人似乎同意的一件事是 JS 中事物的真实性(举个例子去here

现在我在实验中发现了这个奇怪的东西:

(true == 2)false。为什么?

据我所知,2 是一个非零数字,所以它应该被评估为true

【问题讨论】:

    标签: javascript string boolean


    【解决方案1】:

    这是因为当相等运算符的任何一个操作数是数字时,几乎在所有情况下,另一个操作数都会转换为数字,然后比较结果。所以你最终将1(从true转换为2,而不是truetrue进行比较。该规则的唯一例外是nullundefined,以及其默认值(参见下面的题外话)为nullundefined 的对象;将数字与返回的false 进行比较(即使Number(null)0;不要问)。

    the specification 的详细信息,第 11.9.3 节:“抽象等式比较算法”。这是 ES 5.1 中该部分的文本,但该链接指向当前编辑的草稿(这是每年的快照规范所基于的),并且有几个:

    比较 x == y,其中 xy 是值,产生 true 。这样的比较是这样进行的:

    1. 如果Type(x) 与Type(y) 相同,则
      1. 返回执行Strict Equality Comparisonx === y的结果。
    2. 如果 xnullyundefined,则返回 true
    3. 如果 xundefinedynull,则返回 true
    4. 注意:此步骤在B.3.7.2 部分中替换。
    5. 如果Type(x)是Number,Type(y)是String,返回比较结果x ==! ToNumber(y).
    6. 如果Type(x)是String,Type(y)是Number,返回比较结果! ToNumber(x) == y
    7. 如果Type(x) 是BigInt 并且Type(y) 是字符串,那么
      1. n成为! StringToBigInt(y).
      2. 如果 nNaN,则返回 false
      3. 返回比较结果x == n
    8. 如果Type(x)是String,Type(y)是BigInt,返回比较结果y == x.
    9. 如果Type(x) 是布尔值,返回比较结果! ToNumber(x) == y
    10. 如果Type(y) 为布尔值,则返回比较结果x == ! ToNumber(y)。
    11. 如果Type(x) 是String、Number、BigInt 或Symbol 并且Type(y) 是Object,则返回比较结果x == ? ToPrimitive(y).
    12. 如果 Type(x) 是 Object 并且 Type(y) 是 String、Number、BigInt 或 Symbol,则返回比较结果? ToPrimitive(x) == y
    13. 如果 Type(x) 是 BigInt 并且 Type(y) 是 Number,或者如果 Type(x ) 是数字,Type(y) 是 BigInt,则
      1. 如果 xyNaN 中的任何一个,则 +∞? ,或 -∞?,返回 false
      2. 如果(x) = (y),则返回true;否则返回 false
    14. 返回 false

    注意:上面的!s 不是否定,它们表示下面的抽象操作永远不会导致突然完成。详情见this article about reading the spec

    如果您想检查它们是真还是假,您可以使用 bang (!) 或 double-bang (!!) 成语将它们强制转换为布尔值:

    var a = true,
        b = 2;
    alert(a == b);     // "false", 1 !== 2
    alert(!!a == !!b); // "true", true === true
    alert(!a == !b);   // "true", false === false
    a = false;
    b = 0;
    alert(a == b);     // "true", 0 === 0
    alert(!!a == !!b); // "true", false === false
    alert(!a == !b);   // "true", true === true
    

    ...但通常将==!= 与布尔值一起使用并不理想。但它确实出现了。

    我倾向于使用双键,但在 JavaScript 中没有理由过度使用双键。 (在其他一些语言中,有一个论点是双键优于单键,尽管它与 if (!!x) 的一致性有关。在 JavaScript 中,您永远不需要在 if (x) 情况下使用双键,所以...)


    (题外话:大多数 JavaScript 对象的默认值是一个字符串,尽管如果你将它转换为一个数字,通常像 "[object Object]" 最终是 NaN;但是构造函数可以覆盖它valueOftoString 的行为。宿主对象的默认值取决于宿主环境。)

    【讨论】:

      【解决方案2】:

      使用非严格比较 (==) 如果操作数不是同一类型,它们将被强制转换和严格比较,如果操作数是数字或布尔值,则优先选择数字 (@987654321 @)。

      所以true == 2 的计算结果为Number(true) === 2,即1 === 2,这是错误的。

      当然,你总是可以强制比较你想要的东西,这是明确的,可以解决以后难以发现的问题:

      true === Boolean(2) 为真。

      【讨论】:

        【解决方案3】:

        布尔值true 常量被提升为一个数字,即 1。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-05
          • 2018-03-24
          相关资源
          最近更新 更多