Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
750 views
in Technique[技术] by (71.8m points)

string - JavaScript truthiness in boolean to numbers comparison

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 is the truthiness of things in JS (just to give a example go here)

Now I found this odd thing in my experiments:

(true == 2) is false. why?

As far as I know, 2 is a non zero number, so it should be evaluated as true.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is because when either operand of an equality 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 (converted from true) 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". This was the text of that section as of ES 5.1, but that link is to the currently editor's draft (which is what each year's snapshot specification is based on) and there have been several :

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. Return the result of performing Strict Equality Comparison x === y.
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. NOTE: This step is replaced in section B.3.7.2.
  5. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ! ToNumber(y).
  6. If Type(x) is String and Type(y) is Number, return the result of the comparison ! ToNumber(x) == y.
  7. If Type(x) is BigInt and Type(y) is String, then
    1. Let n be ! StringToBigInt(y).
    2. If n is NaN, return false.
    3. Return the result of the comparison x == n.
  8. If Type(x) is String and Type(y) is BigInt, return the result of the comparison y == x.
  9. If Type(x) is Boolean, return the result of the comparison ! ToNumber(x) == y.
  10. If Type(y) is Boolean, return the result of the comparison x == ! ToNumber(y).
  11. If Type(x) is either String, Number, BigInt, or Symbol and Type(y) is Object, return the result of the comparison x == ? ToPrimitive(y).
  12. If Type(x) is Object and Type(y) is either String, Number, BigInt, or Symbol, return the result of the comparison ? ToPrimitive(x) == y.
  13. If Type(x) is BigInt and Type(y) is Number, or if Type(x) is Number and Type(y) is BigInt, then
    1. If x or y are any of NaN, +∞??, or -∞??, return false.
    2. If ?(x) = ?(y), return true; otherwise return false.
  14. Return false.

Note: The !s in the above are not negations, they indicate that the following abstract operation never results in an abrupt completion. Details in this article about reading the spec.

If you wanted to check that they were both truthy or both falsy, 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.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...