11

If I do 0 == "0" it evaluates to true. Try,

if( -777 == "-777" ) alert("same");

alert happens.

And, it's also noticeable that true == "true" doesn't evaluate to true. Try,

if( false == "false" ) alert("same");

alert doesn't happen.

Why is it so?

Real Red.
  • 4,731
  • 8
  • 30
  • 44

8 Answers8

33

The behavior of == is a bit lengthy, but clearly defined in the ecma-262 spec:

11.9.3 The Abstract Equality Comparison Algorithm

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 different from Type(y), go to step 14.
  2. If Type(x) is Undefined, return true.
  3. If Type(x) is Null, return true.
  4. If Type(x) is not Number, go to step 11.
  5. If x is NaN, return false.
  6. If y is NaN, return false.
  7. If x is the same number value as y, return true.
  8. If x is +0 and y is −0, return true.
  9. If x is −0 and y is +0, return true.
  10. Return false.
  11. 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.
  12. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
  13. Return true if x and y refer to the same object or if they refer to objects joined to each other (see 13.1.2). Otherwise, return false.
  14. If x is null and y is undefined, return true.
  15. If x is undefined and y is null, return true.
  16. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
  17. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
  18. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
  19. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
  20. If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
  21. If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
  22. Return false.

Step 16 applies to your former example:

   0 == "0"            // apply 16
≡  0 == toNumber("0")
≡  0 == 0              // apply 7
≡  true

And step 18, then step 16, apply to the latter:

   true == "true"            // apply 18
≡  toNumber(true) == "true"
≡  1 == "true"               // apply 16
≡  1 == toNumber("true")
≡  1 == NaN                  // apply 6
≡  false
Community
  • 1
  • 1
Andrey Fedorov
  • 7,836
  • 20
  • 63
  • 95
11

Doing this:

if(5 == "5")

Makes javascript convert the first 5 to a string. Try this:

if(5 === "5")

The === makes Javascript evaluate type as well.

This is actually a duplicate of this question where it is explained very well.

Community
  • 1
  • 1
Paolo Bergantino
  • 449,396
  • 76
  • 509
  • 431
7

Because Javascript is loosely typed, it will silently cast your variables depending on the operation and the type of the other variables in the operation.

alert ("5" - 1);  // 4  (int)
alert ("5" + 1);  // "51" (string) "+" is a string operator, too
alert ("5" == 5); // true

What you might want to look at is identity checking (===). That makes sure the variables are identical, not merely equal.

alert("5" == 5);  // true, these are equal
alert("5" === 5); // false, these are not identical.

Also see this question: How do the equality and identity comparison operators differ? PHP's implementation is very similar to javascript's.

Community
  • 1
  • 1
nickf
  • 499,078
  • 194
  • 614
  • 709
4

JavaScript has two sets of equality operators:

  • === and !== (strict equality operators)
  • == and != (standard equality operators)

The standard equality operators will do the right comparison if both operands are the same type, but you can get some unexpected results if they're not the same type, for example:

'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true

For that I always recommend to use the strict equality operators (===, !==).

Christian C. Salvadó
  • 723,813
  • 173
  • 899
  • 828
1

Javascript doesn't cast "false" to boolean false, only to the string "false".

You can loosely cast string values to their integer equivalent, thus your first example works.

Chris Ballance
  • 32,056
  • 25
  • 101
  • 147
1

Javascript is a loosely typed language, so typecasts are done at runtime whenever the interpreter feels it is needed. If you compare an integer to a string, it figures that they should be the same type, so, for example, "34" == 34 is true, since the integer would probably be typecasted to a string before the comparison.

The string "false" isn't typecasted into a bool, instead the bool false is typecasted to a string, which would acctually have the value "0", that is, a string containing the number 0, giving "0" == "false", which is obviously false.

If you want to compare the value without automatic typecasting, effectively comparing types as well as values, use a triple equal:

5 === "5" false "string" === "string" true

Seventoes
  • 4,728
  • 3
  • 17
  • 18
1

Why is it so?

Because JavaScript is both loosely-typed, and wildly inconsistent. Not all its design features are well-thought-through; it was created, implemented and deployed incredibly quickly compared to any other programming language, in a rush to get Netscape 2.0 out. It wasn't until long after that it settled down, lost some of the more egregious bugs and became semi-standardised.

Looking for some kind of philosophical rationale for things like the implicit type casting rules is likely to be a fruitless exercise. The only really consistent principle JavaScript adheres to is DWIM, very much in the negative sense.

bobince
  • 498,320
  • 101
  • 621
  • 807
0

JavaScript defines falsey values to be 0, boolean false and undefined. Any string outside of "0" will be true, even if that string is 'false'.

Kind of annoying, really.

ryebr3ad
  • 1,162
  • 3
  • 10
  • 20