101

MDC describes the == operator as follows:

If the two operands are not of the same type, JavaScript converts the operands then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the other operand is converted to a string if possible.

With this in mind, I would evaluate "true" == true as follows:

  1. Are they of the same type? No
  2. Is either operand a number or boolean? Yes
  3. Can we convert both to a number? No (isNaN(Number("true")) // true)
  4. Is either operand a string? Yes
  5. Can we convert the other operand to a string? Yes (String(true) === "true" // true)

I've ended up with the strings "true" and "true", which should evaluate to true, but JavaScript shows false.

What have I missed?

Isaac
  • 1,677
  • 3
  • 15
  • 22

5 Answers5

101

Because "true" is converted to NaN, while true is converted to 1. So they differ.

Like you reported, both are converted to numbers, because at least true can be (see Erik Reppen's comment), and then compared.

MaxArt
  • 22,200
  • 10
  • 82
  • 81
  • 1
    Can you tell me when the step `Can we convert both to a number?` will ever be false then? If even `NaN` is a number, how can this step ever fail? – Isaac Jul 06 '12 at 14:06
  • 6
    Either vs. neither. If both would result in NaN they would switch to string evaluation. If only one can be converted, there's still a number comparison. – Erik Reppen Jul 06 '12 at 14:09
  • 2
    There are actually some odd objects in Javascript that behave quite oddly. For example, XML documents in IE<9 raise an error when you try to convert them to numbers. – MaxArt Jul 06 '12 at 14:10
  • You can see the conversions yourself by doing `Number(true)` and `Number('true')` – Erik Reppen Jul 06 '12 at 14:13
21

The == comparison operator is defined in ECMA 5 as:

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

So, "true" == true is evaluated as:

  1. "true" == ToNumber(true)   (via rule 7)
  2. "true" == 1
  3. ToNumber("true") == 1   (via rule 5)
  4. NaN == 1

===> false

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
nobitavn94
  • 317
  • 3
  • 11
4

Acording to The Abstract Equality Comparison Algorithm

http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

if one of the oprends is a boolean and other is not, boolean is converter to number 0 or 1. so true == "true" is false.

Zohaib Ijaz
  • 21,926
  • 7
  • 38
  • 60
  • Did I infer right in the following way? "true" == true becomes "true" == 1 and then becomes "true" == "1" That's why they return false? – vuquanghoang Sep 01 '17 at 09:16
1

The equality operators (== and !=) use the Abstract Equality Comparison Algorithm to compare two operands.

"true" == true

Since "true" is String and true is Boolean, we need to return the result of "true" == Number(true) (step 7 in the algorithm), which is "true" == 1.

"true" == 1

Since "true" is String and 1 is Number, we need to return the result of Number("true") == 1 (step 5 in the algorithm). Number("true") returns NaN. Now we have NaN == 1.

NaN == 1

Now both operands are of the same type (Number). Acording to the algorithm, if both operands are Number and one of them is NaN, false is returned (step 1.c.i in the algorithm).

eden
  • 105
  • 2
  • 9
0

Explaining considering the scenario true == "true".
Straightway, the above returns false, however, our expectation was true
JavaScript uses Abstract Equality Comparison Algorithm, so according to the algorithm

true == "true"

// If one of the operands is Boolean, convert the Boolean operand to 1 if it is true and +0 if it is false
ConvertToNumber(true) == "true"

1 == "true"

// When the algorithm finds the above statements, it thinks that it needs to do one more conversion - 
// "When comparing a number to a string, try to convert the string to a numeric value"
1 == ConvertToNumber("true)
1 == NaN

// Which returns false
novice2ninja
  • 333
  • 5
  • 5