布尔值与数字比较中的 JavaScript 真实性

JavaScript truthiness in boolean to numbers comparison

本文关键字:JavaScript 真实性 比较 数字 布尔值      更新时间:2023-09-26

我是JavaScript的新手,我正在尝试从互联网资源中学习它。虽然我知道会有很多cr * p材料,但大多数人似乎都同意的一件事是JS中事物的真实性(只是举个例子,请转到此处(

现在我在实验中发现了一件奇怪的事情:

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

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

这是因为

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

规范中的详细信息,第 11.9.3 节:">抽象相等比较算法"。这是从 ES 5.1 开始该部分的文本,但该链接指向当前编辑的草稿(这是每年快照规范的基础(,并且有几个:

比较 x == y,其中 xy 是值,产生此类比较按如下方式执行:

  1. 如果 Type(x( 与 Type(y( 相同,则
    1. 返回执行严格相等比较的结果 x === y
  2. 如果 xy定义,则返回 true
  3. 如果 x定义y,则返回 true
  4. 注意:此步骤在 B.3.7.2 节中替换。
  5. 如果 Type(x( 是 Number,Type(y( 是 String,则返回比较结果 x == ! ToNumber(y(。
  6. 如果 Type(x( 是字符串,Type(y( 是数字,则返回比较结果! ToNumber(x( == y
  7. 如果 Type(x( 是 BigInt,Type(y( 是 String,则
    1. n 成为 ! StringToBigInt(y(.
    2. 如果 nNaN,则返回 false
    3. 返回比较结果 x == n
  8. 如果 Type(x( 是字符串,Type(y( 是 BigInt,则返回比较结果 y == x
  9. 如果 Type(x( 是布尔值,则返回比较结果! ToNumber(x( == y
  10. 如果 Type(y( 是布尔值,则返回比较结果 x == ! ToNumber(y(。
  11. 如果 Type(x( 是字符串、数字、BigInt 或符号,而 Type(y( 是 Object,则返回比较结果 x == ? 到基元(y(。
  12. 如果 Type(x( 是 Object,Type(y( 是 String、Number、BigInt 或 Symbol,则返回比较 结果? ToPrimitive(x( == y
  13. 如果 Type(x( 是 BigInt,Type(y( 是 Number,或者 Type(x( 是 Number,Type(y( 是 BigInt,则
    1. 如果 xyNaN+∞F 或 -∞F 中的任何一个,则返回 false
    2. 如果 R(x( = R(y(,则返回 true;否则返回 false
  14. 返回

注意:上面!不是否定,它们表示下面的抽象操作永远不会导致突然完成。本文中有关阅读规范的详细信息。

如果你想检查它们都是真实的还是伪造的,你可以使用爆炸(!(或双爆炸(!!(成语来强迫他们都使用布尔值:

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 覆盖该行为。主机对象的默认值取决于主机环境。

布尔

true常量提升为一个数字,即 1。

对于非严格比较(==(,如果操作数不是同一类型,它们将被强制转换/强制并严格比较,如果操作数是数字或布尔值(MDN(,则首选数字。

所以true == 2计算出Number(true) === 2哪个是1 === 2,这是假的。

当然,你总是可以强迫事物按照你想要的方式进行比较,这是明确的,可以解决以后难以发现的问题:

true === Boolean(2)是真的。