JavaScript truthiness in boolean to numbers comparison

前端 未结 3 1756
别跟我提以往
别跟我提以往 2020-12-10 18:49

I\'m new to JavaScript and I\'m trying to learn it from internet resources. While I\'m aware that there will plenty of cr*p material, one thing most people seemed to agree i

相关标签:
3条回答
  • 2020-12-10 19:34

    The boolean true constant is promoted to a number, that being 1.

    0 讨论(0)
  • 2020-12-10 19:37

    With non-strict comparison (==) if the operands are not of the same type, they will be casted/coerced and strictly compared, with first preference being to numbers if either operand is a number or boolean (MDN).

    So true == 2 evaluates to Number(true) === 2 which is 1 === 2, which is false.

    Of course you can always force things to compare as you want them to, which is explicit and can solve hard-to-find problems later on:

    true === Boolean(2) is true.

    0 讨论(0)
  • 2020-12-10 19:38

    This is because when either operand of an equivalence operator is a number, in nearly all cases the other operand is converted to a number and then the result is compared. So you're ending up comparing 1 with 2, not true with true. The only exceptions to that rule are null, undefined, and objects whose default value (see off-topic below) is null or undefined; comparing a number to those returns false (even though Number(null) is 0; don't ask).

    Details in the specification, Section 11.9.3: "The Abstract Equality Comparison Algorithm" (HTML version):

    The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

    1. If Type(x) is the same as Type(y), then

      1. If Type(x) is Undefined, return true.

      2. If Type(x) is Null, return true.

      3. If Type(x) is Number, then

        1. If x is NaN, return false.

        2. If y is NaN, return false.

        3. If x is the same Number value as y, return true.

        4. If x is +0 and yis −0, return true.

        5. If x is −0 and y is +0, return true.

        6. Return false.

      4. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.

      5. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.

      6. Return true if x and y refer to the same object. Otherwise, return false.

    2. If x is null and y is undefined, return true.

    3. If x is undefined and y is null, return true.

    4. If Type(x) is Number and Type(y) is String,
      return the result of the comparison x == ToNumber(y).

    5. If Type(x) is String and Type(y) is Number,
      return the result of the comparison ToNumber(x) == y.

    6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.

    7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

    8. If Type(x) is either String or Number and Type(y) is Object,
      return the result of the comparison x == ToPrimitive(y).

    9. If Type(x) is Object and Type(y) is either String or Number,
      return the result of the comparison ToPrimitive(x) == y.

    10. Return false.

    If you wanted to check that they were both truthy or both falsey, you could use the bang (!) or double-bang (!!) idiom to coerce them both to booleans:

    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
    

    ...but usually using == or != with booleans isn't ideal. But it does come up.

    I tend to use the double-bang, but in JavaScript there's no reason to over the bang. (There's an argument for the double over the single in some other languages, though it's a weak one related to consistency with if (!!x). In JavaScript you never need the double-bang in the if (x) case, so...)


    (Off-topic: The default value of most JavaScript objects is a string, though frequently one like "[object Object]" that ends up being NaN if you convert it to a number; but constructor functions can override that behavior via valueOf and toString. The default value of host objects is up to the host environment.)

    0 讨论(0)
提交回复
热议问题